PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Questions : PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

9895

I have a JPA-persisted object model that in4codes_java contains a many-to-one relationship: an in4codes_java Account has many Transactions. A Transaction in4codes_java 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<Transaction> transactions; 

I am able to create an Account object, add in4codes_java transactions to it, and persist the Account in4codes_java object correctly. But, when I create a in4codes_java transaction, using an existing already in4codes_java persisted Account, and persisting the the in4codes_java Transaction, I get an exception:

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

So, I am able to persist an Account that in4codes_java contains transactions, but not a Transaction in4codes_java that has an Account. I thought this was in4codes_java because the Account might not be attached, in4codes_java but this code still gives me the same in4codes_java 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, in4codes_java associated with an already persisted Account in4codes_java object?

Total Answers 22
32

Answers 1 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

The solution is simple, just use the in4codes_jpa CascadeType.MERGE instead of in4codes_jpa CascadeType.PERSIST or CascadeType.ALL.

I have had the same problem and in4codes_jpa CascadeType.MERGE has worked for me.

I hope you are sorted.

0

3

Answers 2 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

This is a typical bidirectional in4codes_jpa consistency problem. It is well in4codes_jpa discussed in this link as well as this in4codes_jpa link.

As per the articles in the previous 2 in4codes_jpa links you need to fix your setters in in4codes_jpa both sides of the bidirectional in4codes_jpa relationship. An example setter for the in4codes_jpa One side is in this link.

An example setter for the Many side is in4codes_jpa in this link.

After you correct your setters you want in4codes_jpa to declare the Entity access type to be in4codes_jpa “Property”. Best practice to declare in4codes_jpa “Property” access type is to move ALL in4codes_jpa the annotations from the member in4codes_jpa properties to the corresponding getters. in4codes_jpa A big word of caution is not to mix in4codes_jpa “Field” and “Property” access types in4codes_jpa within the entity class otherwise the in4codes_jpa behavior is undefined by the JSR-317 in4codes_jpa specifications.

0

3

Answers 3 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Remove cascading from the child entity in4codes_jpa Transaction, it should be just:

@Entity class Transaction { @ManyToOne // no cascading here! private Account account; } 

(FetchType.EAGER can be removed as well in4codes_jpa as it’s the default for @ManyToOne)

That’s all!

Why? By saying “cascade ALL” on the in4codes_jpa child entity Transaction you require in4codes_jpa that every DB operation gets propagated in4codes_jpa to the parent entity Account. If you in4codes_jpa then do persist(transaction), in4codes_jpa persist(account) will be invoked as in4codes_jpa well.

But only transient (new) entities may be in4codes_jpa passed to persist (Transaction in this in4codes_jpa case). The detached (or other in4codes_jpa non-transient state) ones may not in4codes_jpa (Account in this case, as it’s already in4codes_jpa in DB).

Therefore you get the exception in4codes_jpa “detached entity passed to persist”. The in4codes_jpa Account entity is meant! Not the in4codes_jpa Transaction you call persist on.


You generally don’t want to propagate in4codes_jpa from child to parent. Unfortunately in4codes_jpa there are many code examples in books in4codes_jpa (even in good ones) and through the net, in4codes_jpa which do exactly that. I don’t know, in4codes_jpa why… Perhaps sometimes simply copied in4codes_jpa over and over without much thinking…

Guess what happens if you call in4codes_jpa remove(transaction) still having in4codes_jpa “cascade ALL” in that @ManyToOne? The in4codes_jpa account (btw, with all other in4codes_jpa transactions!) will be deleted from the in4codes_jpa DB as well. But that wasn’t your in4codes_jpa intention, was it?

0

5

Answers 4 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Don’t pass id(pk) to persist method or in4codes_jpa try save() method instead of persist().

0

2

Answers 5 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Removing child association cascading

So, you need to remove the in4codes_jpa @CascadeType.ALL from the @ManyToOne in4codes_jpa association. Child entities should not in4codes_jpa cascade to parent associations. Only in4codes_jpa parent entities should cascade to child in4codes_jpa entities.

@ManyToOne(fetch= FetchType.LAZY) 

Notice that I set the fetch attribute to in4codes_jpa FetchType.LAZY because eager fetching is in4codes_jpa very bad for performance.

Setting both sides of the association

Whenever you have a bidirectional in4codes_jpa association, you need to synchronize in4codes_jpa both sides using addChild and in4codes_jpa removeChild methods in the parent in4codes_jpa entity:

public void addTransaction(Transaction transaction) { transcations.add(transaction); transaction.setAccount(this); } public void removeTransaction(Transaction transaction) { transcations.remove(transaction); transaction.setAccount(null); } 

0

3

Answers 6 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Using merge is risky and tricky, so it’s in4codes_jpa a dirty workaround in your case. You in4codes_jpa need to remember at least that when you in4codes_jpa pass an entity object to merge, it stops in4codes_jpa being attached to the transaction and in4codes_jpa instead a new, now-attached entity is in4codes_jpa returned. This means that if anyone has in4codes_jpa the old entity object still in their in4codes_jpa possession, changes to it are silently in4codes_jpa ignored and thrown away on commit.

You are not showing the complete code in4codes_jpa here, so I cannot double-check your in4codes_jpa transaction pattern. One way to get to a in4codes_jpa situation like this is if you don’t have in4codes_jpa a transaction active when executing the in4codes_jpa merge and persist. In that case in4codes_jpa persistence provider is expected to open in4codes_jpa a new transaction for every JPA in4codes_jpa operation you perform and immediately in4codes_jpa commit and close it before the call in4codes_jpa returns. If this is the case, the merge in4codes_jpa would be run in a first transaction and in4codes_jpa then after the merge method returns, the in4codes_jpa transaction is completed and closed and in4codes_jpa the returned entity is now detached. The in4codes_jpa persist below it would then open a in4codes_jpa second transaction, and trying to refer in4codes_jpa to an entity that is detached, giving an in4codes_jpa exception. Always wrap your code inside in4codes_jpa a transaction unless you know very well in4codes_jpa what you are doing.

Using container-managed transaction it in4codes_jpa would look something like this. Do note: in4codes_jpa this assumes the method is inside a in4codes_jpa session bean and called via Local or in4codes_jpa Remote interface.

@TransactionAttribute(TransactionAttributeType.REQUIRED) public void storeAccount(Account account) { ... if (account.getId()!=null) { account = entityManager.merge(account); } Transaction transaction = new Transaction(account,"other stuff"); entityManager.persist(account); } 

0

2

Answers 7 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Probably in this case you obtained your in4codes_jpa account object using the merge logic, in4codes_jpa and persist is used to persist new in4codes_jpa objects and it will complain if the in4codes_jpa hierarchy is having an already persisted in4codes_jpa object. You should use saveOrUpdate in in4codes_jpa such cases, instead of persist.

0

2

Answers 8 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

An old question, but came across the in4codes_jpa same issue recently . Sharing my in4codes_jpa experience here.

Entity

@Data @Entity @Table(name = "COURSE") public class Course { @Id @GeneratedValue private Long id; } 

Saving the entity (JUnit)

Course course = new Course(10L, "testcourse", "DummyCourse"); testEntityManager.persist(course); 

Fix

Course course = new Course(null, "testcourse", "DummyCourse"); testEntityManager.persist(course); 

Conclusion : If the entity class has in4codes_jpa @GeneratedValue for primary key (id), in4codes_jpa then ensure that you are not passing a in4codes_jpa value for the primary key (id)

0

4

Answers 9 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

My Spring Data JPA-based answer: I in4codes_jpa simply added a @Transactional annotation in4codes_jpa to my outer method.

Why it works

The child entity was immediately in4codes_jpa becoming detached because there was no in4codes_jpa active Hibernate Session context. in4codes_jpa Providing a Spring (Data JPA) in4codes_jpa transaction ensures a Hibernate Session in4codes_jpa is present.

Reference:

A beginner’s guide to entity state transitions with JPA and Hibernate

0

2

Answers 10 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

In your entity definition, you’re not in4codes_jpa specifying the @JoinColumn for the in4codes_jpa Account joined to a Transaction. You’ll in4codes_jpa want something like this:

@Entity public class Transaction { @ManyToOne(cascade = {CascadeType.ALL},fetch= FetchType.EAGER) @JoinColumn(name = "accountId", referencedColumnName = "id") private Account fromAccount; } 

EDIT: Well, I guess that would be useful in4codes_jpa if you were using the @Table annotation in4codes_jpa on your class. Heh. 🙂

0

1

Answers 11 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

If nothing helps and you are still in4codes_jpa getting this exception, review your in4codes_jpa equals() methods – and don’t include in4codes_jpa child collection in it. Especially if in4codes_jpa you have deep structure of embedded in4codes_jpa collections (e.g. A contains Bs, B in4codes_jpa contains Cs, etc.).

In example of Account -> in4codes_jpa Transactions:

 public class Account { private Long id; private String accountName; private Set<Transaction> transactions; @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (!(obj instanceof Account)) return false; Account other = (Account) obj; return Objects.equals(this.id, other.id) && Objects.equals(this.accountName, other.accountName) && Objects.equals(this.transactions, other.transactions); // <--- REMOVE THIS! } } 

In above example remove transactions in4codes_jpa from equals() checks. This is because in4codes_jpa hibernate will imply that you are not in4codes_jpa trying to update old object, but you in4codes_jpa pass a new object to persist, whenever in4codes_jpa you change element on the child in4codes_jpa collection. Of course this solutions in4codes_jpa will not fit all applications and you in4codes_jpa should carefully design what you want to in4codes_jpa include in the equals and hashCode in4codes_jpa methods.

0

3

Answers 12 : of PersistentObjectException: detached entity passed to persist thrown by JPA and Hibernate

Even if your annotations are declared in4codes_jpa correctly to properly manage the in4codes_jpa one-to-many relationship you may still in4codes_jpa encounter this precise exception. When in4codes_jpa adding a new child object, Transaction, in4codes_jpa to an attached data model you’ll need to in4codes_jpa manage the primary key value – unless in4codes_jpa you’re not supposed to. If you supply a in4codes_jpa primary key value for a child entity in4codes_jpa declared as follows before calling

Answer Link
jidam
  • Unable to run NoraUI mvn verify goal
  • Unable to run my app on emulator in VS Code
  • Unable to run multiple instances of libVLC(MobileVLCKit) in IOS via flutter framework
  • Unable to run make on griddb source on ubuntu 20.04 (building from source)
  • Unable to run latexindent macOS Monterey 12.0.1
  • Unable to run kotlinc-native command
  • Unable to run JUnit Test… Java.lang.ExceptionInInitializerError (Android Studio)
  • Unable to run java with -Xmx > 966m
  • Unable to run ionic cap run android from wsl2 inorder to start android emulator
  • Unable to run Intel HAXM installer: Cannot start process, the working directory does not exist
  • fs
  • Unable to run Google Analytics sample code