一尘不染

PersistentObjectException:由JPA和Hibernate传递以持久保留的分离实体

hibernate

我有一个JPA持久对象模型,其中包含多对一关系:一个Account具有许多Transactions。A
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,位于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对象关联的?


阅读 240

收藏
2020-06-20

共1个答案

一尘不染

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

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

此链接中提供了很多方面的示例设置器

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

2020-06-20