已分离的实体传递给持久性错误

提交表单时收到此错误:

org.hibernate.PersistentObjectException:传递给persist的分离实体:com.project.pmet.model.Account; 嵌套exception是javax.persistence.PersistenceException:org.hibernate.PersistentObjectException:传递给persist的分离实体:com.project.pmet.model.Account

这是我的实体:

帐户:

@Entity @DynamicInsert @DynamicUpdate public class Account { @Id @GeneratedValue private Integer id; @Column(nullable = false) private String login; @Column(nullable = false) private String password; @Column(nullable = false) private String email; @ManyToOne @JoinColumn(name = "team_id") private Team team; @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner") private List ownedTeams; ... 

球队:

 @Entity @DynamicInsert @DynamicUpdate public class Team { @Id @GeneratedValue private Integer id; @Column(nullable = false) private String name; @ManyToOne @JoinColumn(name = "owner_id", nullable = false) private Account owner; @OneToMany(cascade = CascadeType.ALL, mappedBy = "team") private List members; ... 

这是Controller的一部分:

  @ModelAttribute("team") public Team createTeamObject() { return new Team(); } @RequestMapping(value = "/teams/create-team", method = RequestMethod.GET) public String getCreateTeam(@ModelAttribute("team") Team team, Principal principal) { logger.info("Welcome to the create team page!"); Account owner = accountService.findOneByLogin(principal.getName()); team.setOwner(owner); team.setMembers(new AutoPopulatingList(Account.class)); return "teams"; } @RequestMapping(value = "/teams/create-team", method = RequestMethod.POST) public String postCreateTeam(@ModelAttribute("team") Team team) { logger.info("Team created!"); teamService.save(team); return "redirect:/teams.html"; } 

forms:

 
...

我究竟做错了什么?

 teamService.save(team); 

Save方法只接受瞬态对象。 你可以在这里找到什么瞬态对象

Transient - an object is transient if it has just been instantiated using the new operator, and it is not associated with a Hibernate Session. It has no persistent representation in the database and no identifier value has been assigned. Transient instances will be destroyed by the garbage collector if the application does not hold a reference anymore. Use the Hibernate Session to make an object persistent (and let Hibernate take care of the SQL statements that need to be executed for this transition).

您正在获取Team对象,并且您正在尝试将其持久保存到DB,但该对象中包含Account对象并且该Account对象已分离(表示该对象的实例已保存到DB中但该对象不在会话中)。 Hibernate试图保存它,因为你已经指定:

 @OneToMany(cascade = CascadeType.ALL, .... 

因此,您可以通过几种方法解决问题:

1)不要使用CascadeType.ALL配置。 帐户对象可用于多个团队(至少域结构允许),更新操作可能会更新所有团队的帐户 – 这意味着不应使用团队更新启动此操作。 我会从那里删除cascade参数(默认值是没有级联操作),如果你真的需要使用MERGE / DELETE配置。 但如果你真的需要坚持下去,那么请看选项#2

2)使用’saveOrUpdate()’方法代替’save()’。 ‘saveOrUpdate()’方法接受瞬态和分离的对象。 但是这种方法的问题在于设计:在保存Team对象时是否真的需要插入/更新帐户? 我会将其拆分为两个操作,并阻止从团队更新帐户。

希望这可以帮助。

发生错误是因为已设置id 。 Hibernate区分瞬态和分离对象,并且持久化仅适用于瞬态对象。

 isteamService.save(team); 

在此操作中无法加载id,因为是@GeneratedValue

由于您的id是自动生成的值,因此请勿从客户端发送。 我有同样的问题。 确保您没有为自动生成的属性提供值。