PersistentObjectException:传递给 JPA 和 Hibernate 持久抛出的分离实体

新手上路,请多包涵

我有一个包含多对一关系的 JPA 持久对象模型:一个 Account 有很多 Transactions 。一个 Transaction 有一个 Account

这是代码片段:

 @Entity
public class Transaction {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne(cascade = {CascadeType.ALL},fetch= FetchType.EAGER)
    private Account fromAccount;
....

@Entity
public class Account {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @OneToMany(cascade = {CascadeType.ALL},fetch= FetchType.EAGER, mappedBy = "fromAccount")
    private Set<Transaction> transactions;

我能够创建一个 Account 对象,向其添加事务,并正确保留 Account 对象。但是,当我创建交易时, 使用现有的已经持久化的 Account 并持久 化 Transaction ,我得到一个异常:

由以下原因引起:org.hibernate.PersistentObjectException:传递给持久化的分离实体:com.paulsanwald.Account at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)

因此,我能够保留包含事务的 Account ,但不保留包含 Account 的事务。我认为这是因为 Account 可能没有附加,但这段代码仍然给我同样的例外:

 if (account.getId()!=null) {
    account = entityManager.merge(account);
}
Transaction transaction = new Transaction(account,"other stuff");
 // the below fails with a "detached entity" message. why?
entityManager.persist(transaction);

如何正确保存 Transaction ,与已经存在的 Account 对象相关联?

原文由 Paul Sanwald 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 548
2 个回答

这是一个典型的双向一致性问题。在 此链接此链接中对此进行了很好的讨论。

根据前两个链接中的文章,您需要修复双向关系两侧的设置器。一侧的示例设置器位于 此链接中。

许多方面的示例设置器位于 此链接中。

更正设置器后,您希望将实体访问类型声明为“属性”。声明“属性”访问类型的最佳做法是将所有注释从成员属性移动到相应的获取器。一个重要的警告是不要在实体类中混合“字段”和“属性”访问类型,否则 JSR-317 规范未定义该行为。

原文由 Sym-Sym 发布,翻译遵循 CC BY-SA 3.0 许可协议

解决方案很简单,只需使用 CascadeType.MERGE 代替 CascadeType.PERSISTCascadeType.ALL

我遇到了同样的问题, CascadeType.MERGE 对我有用。

我希望你被排序。

原文由 ochiWlad 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题