11.4 对于报错信息PersistentObjectException:的处理| Java Debug 笔记

170 阅读1分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>

提问:如何处理PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

我有一个包含多对一关系的JPA持久对象模型:一个帐户有很多交易。 交易有一个帐户。

这是一段代码:

@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对象。 但是,当我创建交易时,使用一个已经存在的现有帐户,并保留该交易,我得到了一个异常:

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

因此,我能够保留包含交易的帐户,但不能保留具有帐户的交易。 我认为这是因为可能没有为帐户附加值,但是此代码仍然给我同样的异常:


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

回答1:

这是一个典型的双向一致性问题。

您需要在双向关系的两侧修复设置器,这个连接提供了一份代码

在更正了设置者之后,您想要将实体访问类型声明为“属性”。 声明“属性”访问类型的最佳解决方案是将所有注释从成员属性移至相应的getter。 一个大的警告是不要在实体类中混合使用“字段”和“属性”访问类型,否则JSR-317规范未定义其行为。