PersistentObjectException:由 JPA 和 Hibernate 传递给 persist 的分离实体

2022-08-31 05:06:56

我有一个JPA持久化的对象模型,它包含一个多对一的关系:an有很多。A 有一个 。AccountTransactionsTransactionAccount

下面是代码片段:

@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;

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

Caused by: org.hibernate.PersistentObjectException: de detached entity pass to persist: com.paulsanwald.Account at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141)

因此,我能够持久保存一个包含事务的事务,但不能持久保存具有 .我以为这是因为可能没有附加,但这段代码仍然给了我同样的例外:AccountAccountAccount

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);

如何正确保存与已持久化对象关联的 .TransactionAccount


答案 1

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

我遇到了同样的问题,并为我工作。CascadeType.MERGE

我希望你被排序。


答案 2

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

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

Many side 的一个示例 setter 在此链接中。

更正资源库后,要将实体访问类型声明为“属性”。声明“属性”访问类型的最佳做法是将所有批注从成员属性移动到相应的 getter。需要注意的一点是,不要在实体类中混合使用“Field”和“Property”访问类型,否则 JSR-317 规范无法定义该行为。


推荐