File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

detached entity vs. removed entity

 
Helen Ge
Ranch Hand
Posts: 68
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Can someone help me to better understand the difference between the detached entity and removed entity?

is removed entity just marked for remove but actually not removed yet until next commit/flush? I thought the name for removed entity is confusing.

is the persist() call can reactive the removed entity back to managed entity? but will be illegal for the detached entity?

I would appreciate if someone can give me couple simple examples simulate the reallife cases...

thanks in advance,

Helen Ge

SCJP
SCWCD
SCJWD
 
Pedro Erencia
Ranch Hand
Posts: 70
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Helen,


The remove is a "database state", as it denotates which is the state of the entity relative to the database - though it is not a "real" state but a programmed state, it will synchronize with db on next commit/flush -. It's equivalent to somethink like a persisted or merged state.
The detached state is concerned about the state of the object relative to the persistence context ( EntityManager ).
Detached has nothing to do with the entity's database state. A persisted entity can be detached.

For example.

EntityX x = new EntityX();
em.getUserTransaction().begin();
em.persist(x);
em.getUserTransaction().commit();
// now the x object is detached.

Entity x = em.find(EntityX.class, 1);
em.getUserTransaction().begin();
em.remove(x);
// now x object is removed, but not detached.
em.getUserTransaction().commit();

// x object is detached.

Hope it helps.
 
Helen Ge
Ranch Hand
Posts: 68
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pedro,

Your explaination always helps me! ( I remembered you helped me for my last question).

But I still feel a little foggy -

For your second example:

Entity x = em.find(EntityX.class, 1);
em.getUserTransaction().begin();
em.remove(x);
// now x object is removed, but not detached.
em.getUserTransaction().commit();

// x object is detached.


right after the em.remove(x) call but before the commit() call, if we put the call em.persist(x), then the x will become managed again. Is it correct? But if we call persist(x) after the commit(), then the EntityExistsException will be thrown, right?




please bear with me if my question is not clear enough.

thanks


Helen Ge

SCJP
SCWCD
SCJWD
 
Pedro Erencia
Ranch Hand
Posts: 70
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Your explaination always helps me! ( I remembered you helped me for my last question).


I'm glad about it




right after the em.remove(x) call but before the commit() call, if we put the call em.persist(x), then the x will become managed again. Is it correct?


Yes, it is.

But if we call persist(x) after the commit(), then the EntityExistsException will be thrown, right?


I'm not 100% sure about that, but i think persist requires a transactional context to be executed. - supposing we are not using extended persistence contexts - if we do..

em.remove(x);
// now x object is removed, but not detached.
em.getUserTransaction().commit();
em.persist(x);

we'll get an TransactionRequiredException.


but if we do..

em.remove(x);
em.clear();
em.persist(x);
em.getUserTransaction().commit();

then we'll get EntityExistsException.

Anyway, i'm going to test it now
 
Benoît de Chateauvieux
Ranch Hand
Posts: 183
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pedro,

Did you test your example ?
I'm not sure it will work (but I don't have a JPA compliant Application Server to test it).



For me, the entity x obtained in the first line is detached.
As described in 3.1.1 EntityManager Interface
The find and getReference methods are not required to be invoked within a transaction context. If an entity manager with transaction-scoped persistence context is in use, the resulting entities will be detached;


And if you try to remove a detached entity, you'll have an IllegalArgumentException.
As described in 3.2.2 Removal
If X is a detached entity, an IllegalArgumentException will be thrown by the remove operation (or the transaction commit will fail).


Can you confirm ?
Thanks,

Beno�t
 
Pedro Erencia
Ranch Hand
Posts: 70
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Beno�t,

yes, you're right. I didn't realize when i put the example, the find must be substituted by a new for the example to make sense, thanks and sorry .

Using a new entity insted of a find i've tested what i mentioned, and that's what i get..




A TransactionRequiredException is thrown



A PersistentObjectException is thrown.
 
Helen Ge
Ranch Hand
Posts: 68
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Pedro,

Since I don't have the real life EJB experience and I don't have the JPA app server to test the code either, so what I am learning now is just based on the writing materials. Here I found the MZ's note regarding the persistence on the detached entities:



The semantics of the persist operation, applied to an entity X are as follows:

If X is a NEW entity, it becomes MANAGED. The entity X will be entered into the database at or before transaction commit or as a result of the flush operation.

If X is a preexisting MANAGED entity, it is IGNORED by the persist operation. However, the persist operation is cascaded to entities referenced by X, if the relationships from X to these other entities is annotated with the cascade=PERSIST or cascade=ALL annotation element value or specified with the equivalent XML descriptor element.

If X is a REMOVED entity, it becomes MANAGED.

If X is a DETACHED object, the EntityExistsException may be thrown when the persist operation is invoked, or the EntityExistsException or another PersistenceException may be thrown at flush or commit time.

For all entities Y referenced by a relationship from X, if the relationship to Y has been annotated with the cascade element value cascade=PERSIST or cascade=ALL, the persist operation is applied to Y.




For your tested code #1


Can you let me know is this on the last line you got the TransactionRequiredException? I got confused with MZ's note, it says
If X is a DETACHED object, the EntityExistsException may be thrown when the persist operation is invoked



For your tested code #2


Can you tell me which line the PersistenceObjectException is thrown? Is this on the second em.persist(o) call?

if the em.clear() is detaching the object, then next em.persist(o) call should has the same effect as your code #1, why it throws different exception?


Study the persistent entity on SCBCD is the hardest part to me...

thanks

Helen Ge

SCJP
SCWCD
SCJWD
 
Pedro Erencia
Ranch Hand
Posts: 70
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Helen,

For your tested code #1

code:


Order o=new Order();
context.getUserTransaction().begin();
o.setOrderName("S/W Order");
em.persist(o);
context.getUserTransaction().commit();
em.persist(o);

--------------------------------------------------------------------------


A TransactionRequiredException is thrown




Can you let me know is this on the last line you got the TransactionRequiredException? I got confused with MZ's note, it says

quote:If X is a DETACHED object, the EntityExistsException may be thrown when the persist operation is invoked


Yes, it's on the last line.

Also from MZ Study guide

The persist, merge, remove, and refresh methods MUST be invoked within a transaction context
when an entity manager with a transaction-scoped persistence context is used. If there is no
transaction context, the javax.persistence.TransactionRequiredException is thrown


For your tested code #2

code:



Order o=new Order();
context.getUserTransaction().begin();
o.setOrderName("S/W Order");
em.persist(o);
em.clear();
em.persist(o);
context.getUserTransaction().commit();


--------------------------------
A PersistentObjectException is thrown.





Can you tell me which line the PersistenceObjectException is thrown? Is this on the second em.persist(o) call?


Yes, it's on the second call to persist.


if the em.clear() is detaching the object, then next em.persist(o) call should has the same effect as your code #1, why it throws different exception?


In the second example the second call to persist is inside the boundaries of the transaction, so no TransactionRequired will be throw since there is a transaction; but since o is a detached entity your quote on MZs will apply.

Hope it helps.
 
I agree. Here's the link: http://aspose.com/file-tools
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic