• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Liutauras Vilda
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Saloon Keepers:
  • Scott Selikoff
  • Tim Holloway
  • Piet Souris
  • Mikalai Zaikin
  • Frits Walraven
Bartenders:
  • Stephan van Hulst
  • Carey Brown

detached entity vs. removed entity

 
Ranch Hand
Posts: 68
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
 
Ranch Hand
Posts: 70
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
 
Ranch Hand
Posts: 183
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
You got style baby! More than this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
reply
    Bookmark Topic Watch Topic
  • New Topic