13

I have been searching JPA entity life cycle nowadays. But now , there are some missing points about entity life cyle. I have found following graphic in one of stackoverflow posts and keep in mind this diagram had been upvoted.

JPA Entity Life Cycle

According to this diagram , when we persist entity it becomes managed . OK . No problem . When we commit , data goes to database. OK . No problem. But diagram shows us this commit operation made entity detached ! Let's look at below psuedo code.

entityManager.persist(entity);
transaction.commit(); // action completed and entity has become detached.(According to the diagram.)
entityManager.remove(entity); //Attention this step please .

in previous step(commit step). So how is it possible to remove a detached object? If this entity becomes detached , we all know it is not possible to manage a detached entity since it has no assocaiton with persistence context anymore.

So how is it possible to remove a detached object? Could you please clarify me at this point ? Thanks in advance !

Mesut Dogan
  • 572
  • 7
  • 16
  • you mean "entityManager.remove(entity); // entity is already detached here?" please clarify this detail – MWiesner Aug 12 '15 at 12:24
  • I mean "if entity becomes detached after commit(according to the graph), how is it possible to remove this entity ? Because detached means it is no longer associated with persistence context and can not perform any action on detached entity " – Mesut Dogan Aug 12 '15 at 12:39
  • 1
    depends on the PersistenceContext ... see http://www.datanucleus.org/products/accessplatform_4_2/jpa/object_lifecycle.html EM.close can be the operation that detaches it, depending on the context – Neil Stockton Aug 12 '15 at 13:56

4 Answers4

9

Entity can become detached in one of the following ways (there could be more ways):

  1. When the transaction (in transaction-scoped persistence context) commits, entities managed by the persistence context become detached.

  2. If an application-managed persistence context is closed, all managed entities become detached.

  3. Using clear method

  4. using detach method

  5. rollback

  6. In extended persistence context when a stateful bean is removed, all managed entities become detached.

I think the problem could be the difference between application managed, user managed, extended persistence contexts.

Atul
  • 2,673
  • 2
  • 28
  • 34
  • Hello please see the pL4GU33's answer . It seems there is a mismatch between your answers. Thanks – Mesut Dogan Aug 12 '15 at 15:24
  • No,that is a missunterstanding, all that he say is true. As i said in my answer, the picture is right in TRANSACTION scope context) but NOT in all possible cases. (like my example) – pL4Gu33 Aug 12 '15 at 15:33
  • Yes, I think the confusion is probably because of the scope of the persistence context. Is it ApplicationManaged? Is the EM created something like: EntityManager em = emf.createEntityManager(); ? If the remove operation removed the entity, the entity was managed before remove which would mean the the scope of persistence context(em) was not transaction (Either Extended or Application Managed). otherwise, it would throw exception https://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#remove(java.lang.Object) – Atul Aug 12 '15 at 16:50
  • Thank you all. Firstly I should learn differences between app managed context and transaction managed context. – Mesut Dogan Aug 12 '15 at 19:04
  • Strangely in my experience when transaction (at least managed by Spring with @Transactional) does NOT detach the entity. I could save the new updated value to databse only with the call to setter in a new transaction without addressing to merge method – Andrey M. Stepanov Feb 25 '19 at 23:15
5

2 things : the state remove and detached are different :Removed means that the entity is still managed and will trigger a deletion in persitence layer on the flush, Detached means that the entity is no longer managed and that the changes made on it won't be reported to database.

Your entity state is related to an entityManager. Managed means that the EM tracks all changes made on it and will report them on database at flush time.

You must understand that reporting changes to the database has no sense outside of a transaction (JPA support only transacted access to DB and only in isolation level READ_COMMITED).

Tracking change on the entity once the transaction in which it has been retrieved has expired has so no sense as EntityManager won't be able to alter database state outside of a transaction.

That's why The EntityManager in JPA is designed to be created for each unit of work (contrary to the persistenceUnit, ie. the entityManagerFactory which is created once for the whole application).

In consequence the EntityManager should have the same scope than the transaction and should be released just after the commit (which is the case when you let the container manage the entityManager lifecycle for you).

That's also the reason why JPA does not support nested transactions.

Gab
  • 7,869
  • 4
  • 37
  • 68
  • See also http://stackoverflow.com/questions/22772980/struggling-to-understand-entitymanager-proper-use/22773758#22773758 – Gab Aug 12 '15 at 14:24
4

This picture is from openjpa but IMO (other opinions are welcome) its a bit wrong?! (In EE with TRANSACTION Scope its okay) But in a JAVA SE Example like this: ....

EntityTransaction et = em.getTransaction();
et.begin();
em.persist(entity);
et.commit();
System.out.println(em.contains(entity)); // true
em.detach(entity);
System.out.println(em.contains(entity)); // false
entity = em.merge(entity);
System.out.println(em.contains(entity)); // true

The entity is detached after detached method. After commit it stays in the entity persistence context.

For your question: when you have a detached object you can use merge to reattach it to the persistence context.

pL4Gu33
  • 2,045
  • 16
  • 38
1

JPA Spec:

3.3 Persistence Context Lifetime and Synchronization Type
...
An EntityManager with an extended persistence context maintains its references to the entity objects
after a transaction has committed. Those objects remain managed by the EntityManager, and they can
be updated as managed objects between transactions.
...
3.3.2 Transaction Commit
The managed entities of a transaction-scoped persistence context become detached when the transaction
commits; the managed entities of an extended persistence context remain managed.

Note that an application-managed entity manager (which is what you will typically use in Java SE) always uses an extended persistence context.

So the short answer to your question is: when using a transaction-scoped PC, commit will cause detachment; when using an extended PC, commit will NOT cause detachment.

JL_SO
  • 1,742
  • 1
  • 25
  • 38