Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detach an entity from JPA/EJB3 persistence context

Tags:

java

orm

jpa

People also ask

How do you remove entity from persistence context?

You can prevent that by calling the flush method on the EntityManager. After you've done that, you can remove a specific entity from the persistence context by calling the detach method or you can call the clear method to clear the persistence context completely. Query query = em.

What does EntityManager detach do?

detach. Remove the given entity from the persistence context, causing a managed entity to become detached. Unflushed changes made to the entity if any (including removal of the entity), will not be synchronized to the database. Entities which previously referenced the detached entity will continue to reference it.

What is JPA detach?

A detached entity (a.k.a. a detached object) is an object that has the same ID as an entity in the persistence store but that is no longer part of a persistence context (the scope of an EntityManager session).


(may be too late to answer, but can be useful for others)

I'm developing my first system with JPA right now. Unfortunately I'm faced with this problem when this system is almost complete.

Simply put. Use Hibernate, or wait for JPA 2.0.

In Hibernate, you can use 'session.evict(object)' to remove one object from session. In JPA 2.0, in draft right now, there is the 'EntityManager.detach(object)' method to detach one object from persistence context.


No matter which JPA implementation you use, Just use entityManager.detach(object) it's now in JPA 2.0 and part of JEE6.


If you need to detach an object from the EntityManager and you are using Hibernate as your underlying ORM layer you can get access to the Hibernate Session object and use the Session.evict(Object) method that Mauricio Kanada mentioned above.

public void detach(Object entity) {
    org.hibernate.Session session = (Session) entityManager.getDelegate();
    session.evict(entity);
}

Of course this would break if you switched to another ORM provider but I think this is preferably to trying to make a deep copy.


Unfortunately, there's no way to disconnect one object from the entity manager in the current JPA implementation, AFAIR.

EntityManager.clear() will disconnect all the JPA objects, so that might not be an appropriate solution in all the cases, if you have other objects you do plan to keep connected.

So your best bet would be to clone the objects and pass the clones to the code that changes the objects. Since primitive and immutable object fields are taken care of by the default cloning mechanism in a proper way, you won't have to write a lot of plumbing code (apart from deep cloning any aggregated structures you might have).


As far as I know, the only direct ways to do it are:

  1. Commit the txn - Probably not a reasonable option
  2. Clear the Persistence Context - EntityManager.clear() - This is brutal, but would clear it out
  3. Copy the object - Most of the time your JPA objects are serializable, so this should be easy (if not particularly efficient).