*
The moose likes EJB Certification (SCBCD/OCPJBCD) and the fly likes detached entity vs. removed entity Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » EJB Certification (SCBCD/OCPJBCD)
Bookmark "detached entity vs. removed entity" Watch "detached entity vs. removed entity" New topic
Author

detached entity vs. removed entity

Helen Ge
Ranch Hand

Joined: May 24, 2005
Posts: 68
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


SCJP,SCWCD,SCDJWS,SCBCD
Pedro Erencia
Ranch Hand

Joined: Apr 03, 2008
Posts: 70
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

Joined: May 24, 2005
Posts: 68
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

Joined: Apr 03, 2008
Posts: 70

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

Joined: Aug 10, 2007
Posts: 183
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


SCJP5 | SCBCD5 | SCEA5 Part 1
Pedro Erencia
Ranch Hand

Joined: Apr 03, 2008
Posts: 70
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

Joined: May 24, 2005
Posts: 68
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

Joined: Apr 03, 2008
Posts: 70
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.
 
 
subject: detached entity vs. removed entity
 
Similar Threads
Error: detached entity passed to persist
entity state question
Is a removed entity instance is not associated with a persistence context?
how to find if an entity is detached
Section 3.2.1 of EJB 3.0 Persistence Specs