JPA/Hibernate: detached entity passed to persist

14.5K    Asked by AashnaSaito in Java , Asked on Jun 9, 2021

What is a detached entity passed to persist? what is that detached entity the message talks about? 

 I have a JPA-persisted object model that contains a many-to-one relationship: an Account has many Transactions. A Transaction has one Account.

Here's a snippet of the code:

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

I am able to create an Account object, add transactions to it, and persist the Account object correctly. But, when I create a transaction, using an existing already persisted Account, and persisting 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)

So, I am able to persist an Account that contains transactions, but not a Transaction that has an Account. I thought this was because the Account might not be attached, 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);

How can I correctly save a Transaction, associated with an already persisted Account object?

Answered by elonjigar

This is a standard bidirectional compatibility problem. It is well discussed in this link as well as this link.

As per the provisions in the previous 2 links you require to fix your setters in both parties of the bidirectional connection. An example setter for the One side is in this link.

A standard-setter for the Many sides is in this link.

After you change your setters you want to declare the Entity access type to be "Property". Best practice to declare the "Property" access-type is to move ALL the explanations from the member properties to the corresponding getters. A big word of warning is not to mix "Field" and "Property" access standards within the entity class unless the behavior is undefined by the JSR-317 specs.

A detached entity (a.k.a. a detached object) is an object that has the same ID as an entity in the persistence store but that is no longer part of a persistence context (the scope of an EntityManager session).



Your Answer

Answer (1)

The "Detached entity passed to persist" error in JPA/Hibernate occurs when you attempt to persist an entity that was previously fetched from the database and is now in a detached state. This typically happens when an entity has been retrieved in one transaction, and then an attempt is made to persist it in another transaction.


To resolve this issue, you can:

Reattach the Entity: If you intend to update the entity, you can reattach it to the current persistence context using the merge() method. This method merges the state of the detached entity with the persistence context and returns a managed entity, which can then be persisted.

entityManager.merge(entity);

Use persist() for New Entities: If the entity is new and not yet managed by the persistence context, you should use the persist() method to make it persistent.

entityManager.persist(entity);

Fetch and Update in the Same Transaction: If possible, perform both fetching and updating of entities within the same transaction to keep them attached to the persistence context.

Check Cascade Settings: Ensure that cascade settings are appropriately configured for relationships between entities. If cascading is set to ALL or MERGE, associated entities will be persisted along with the main entity.

By applying these strategies, you can handle the "Detached entity passed to persist" error effectively in your JPA/Hibernate application.




6 Months

Interviews

Parent Categories