我试图保存团队,然后拯救他的所有成员,但我面临着这个错误。我找了很多这个常见的问题,但我不知道问题出在哪里。
错误:
org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.hackathon.web.domain.Member#com.hackathon.web.domain.MemberId@dc6]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:2648) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3491) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:3354) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:3768) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.action.internal.EntityUpdateAction.execute(EntityUpdateAction.java:201) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478) ~[hibernate-core-5.4.30.Final.jar:5.4.30.Final]
团队等级:
public class Team {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="teamid")
private Long teamID;
private String name;
@ToString.Exclude
@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER,orphanRemoval = true)
@JoinColumn(name="teamid")
private List<Member> members;
@OneToMany(mappedBy = "team",cascade = CascadeType.ALL,fetch = FetchType.EAGER)
@ToString.Exclude
private Set<Mark> marks;
@ManyToOne
@JoinColumn(name = "mentorid",insertable = true, updatable = true)
@ToString.Exclude
private Mentor mentor;
@ManyToOne
@JoinColumn(name = "administratorid",insertable = true, updatable = true)
@ToString.Exclude
private Administrator administrator;
@ManyToOne
@JoinColumn(name = "hackathonid",insertable = true, updatable = true)
@ToString.Exclude
private Hackathon hackathon;}
成员类别:
public class Member {
@EmbeddedId
private MemberId id;
private String name;
private String mail;
private String lastName;
private String role;
@ManyToOne(fetch = FetchType.LAZY,cascade = ALL)
@JoinColumn(name="teamid",insertable = false, updatable = false )
private Team team;}
MemberId类:
public class MemberId implements Serializable {
@GeneratedValue(strategy = GenerationType.AUTO)
private Long memberID;
@Column(insertable=true, updatable=true)
private Long teamID;}
控制器:
@PostMapping("/administrator/addTeam")
public String saveTeam(Model model,
@NotNull @Valid
@ModelAttribute Team team,
BindingResult bindingResult,
HttpServletRequest request){
if(team.getAdministrator() == null){
Administrator administrator = (Administrator) request.getSession().getAttribute("user");
team.setAdministrator(administrator);
}
Team teamForSave = new Team(0L,team.getName(),new ArrayList<>(),new HashSet<>(), team.getMentor(), team.getAdministrator(), team.getHackathon());
Team savedTeam = teamService.save(teamForSave);
if(team.getMembers() != null ) {
for (Member m :
team.getMembers()) {
Member member = new Member(new MemberId(0L, savedTeam.getTeamID())
,m.getName()
,m.getMail()
,m.getLastName()
,m.getRole()
,savedTeam);
Member savedMember = memberService.save(member);
}
}
model.addAttribute("team",savedTeam);
return "team";
}
Hibernate日志:
Hibernate: insert into team (administratorid, hackathonid, mentorid, name) values (?, ?, ?, ?)
Hibernate: select member0_.memberid as memberid1_5_2_, member0_.teamid as teamid2_5_2_, member0_.last_name as last_nam3_5_2_, member0_.mail as mail4_5_2_, member0_.name as name5_5_2_, member0_.role as role6_5_2_, team1_.teamid as teamid1_7_0_, team1_.administratorid as administ3_7_0_, team1_.hackathonid as hackatho4_7_0_, team1_.mentorid as mentorid5_7_0_, team1_.name as name2_7_0_, marks2_.teamid as teamid2_4_4_, marks2_.markid as markid1_4_4_, marks2_.markid as markid1_4_1_, marks2_.teamid as teamid2_4_1_, marks2_.comment as comment3_4_1_, marks2_.complexity as complexi4_4_1_, marks2_.design as design5_4_1_, marks2_.efficiency as efficien6_4_1_, marks2_.judgeid as judgeid7_4_1_ from member member0_ left outer join team team1_ on member0_.teamid=team1_.teamid left outer join mark marks2_ on team1_.teamid=marks2_.teamid where member0_.memberid=? and member0_.teamid=?
Hibernate: insert into member (last_name, mail, name, role, memberid, teamid) values (?, ?, ?, ?, ?, ?)
Hibernate: update member set last_name=?, mail=?, name=?, role=? where memberid=? and teamid=?
因此,团队被正确保存,第一个成员也是,然后发生此错误。用例为:我在表单上添加新的团队,包括将成员添加到表中,为每个成员设置randomNegativeId以跟踪从表中删除,设置团队ID -1以在视图中显示正确的表单。但在这里控制器即时通讯创建新的团队和复制值,所以我不知道为什么它不工作。我试图保存所有一次与级联,但然后错误是,teamid列是空的成员。我真的需要帮助。先谢谢你了
2条答案
按热度按时间wgx48brx1#
如果使用cascade= cascadeType.all,则不应先保存团队,然后再单独保存成员。这会导致交易混乱。你应该做的是先将成员设置为teamForSave,然后保存它:
你也应该对马克做同样的事情。如果你想手动保存子实体,就像你在控制器中做的那样,删除实体(团队)中的cascadeType.All
mnowg1ta2#
首先,不要让控制器处理存储库交互,这通常是一个不好的实践。而是使用服务类。但是,如果不考虑这个问题,类就像这样
就是这样由于级联设置为ALL(其中还包括PERSIST),因此将保存成员。重要的是不要手动设置id,除非它不是自动id分配策略。
您的控制器将成为
当然,您需要注入TeamService,就像您为团队存储库所做的那样。
PS:我真的不知道teamService到底是一个Service还是一个Repositoy。如果它已经是一个服务,那么只需替换.保存()方法中的代码