Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does JPA's commit() method make entity detached?

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 !

like image 641
Mesut Dogan Avatar asked Aug 12 '15 12:08

Mesut Dogan


2 Answers

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.

like image 56
Gab Avatar answered Sep 18 '22 11:09

Gab


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.

like image 38
Atul Avatar answered Sep 19 '22 11:09

Atul