This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.

Question: how to deal with PersistentObjectException: detached entity passed to persist thrown by the JPA and Hibernate

I have a JPA persistent object model with a many-to-one relationship: there are many transactions in one account. Transactions have an account.

Here is the code:

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

    @ManyToOne(cascade = {CascadeType.ALL},fetch= FetchType.EAGER)
    privateAccount 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;
Copy the code

I was able to create an Account object, add transactions to it, and persist the Account object correctly. However, when I create a transaction, using an existing account that already exists, and keeping the transaction, I get an exception:

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

Therefore, I am able to keep the account that contains the transaction, but NOT the transaction that has the account. I think this is because there may be no added value to the account, but this code still gives me the same exception:


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);
Copy the code

Answer 1:

This is a classic two-way consistency problem.

You need to fix the setters on both sides of the bidirectional relationship, and this connection provides a code.

After correcting the setter, you want to declare the entity access type as “properties.” The best solution for declaring the “property” access type is to move all comments from the member property to the corresponding getter. One big caveat is not to mix “field” and “attribute” access types in entity classes, otherwise the JSR-317 specification does not define its behavior.