I have a java EE project using JPA (transaction-type="JTA"), hibernate as provider. I write my beans to handle the CRUD things. The program running in JBOSS 7 AS.
I have an EntityManagerDAO :
@Stateful public class EntityManagerDao implements Serializable { @PersistenceContext(unitName = "dtdJpa") private EntityManager entityManager; @TransactionAttribute(TransactionAttributeType.REQUIRED) public Object updateObject(Object object) { object = entityManager.merge(object); return object; } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void createObject(Object object) { entityManager.persist(object); } public void refresh(Object object) { entityManager.refresh(object); } public <T> T find(Class<T> clazz, Long id) { return entityManager.find(clazz, id); } @TransactionAttribute(TransactionAttributeType.REQUIRED) public void deleteObject(Object object) { entityManager.remove(object); } }
but when I invoke deleteObject
, this exception comes out.
java.lang.IllegalArgumentException: Removing a detached instance com.test.User#5
How is this caused and how can I solve it?
JPA - Removing Entities. Entities can be deleted from database by calling EntityManager#remove(anEntity) method. This operation must be invoked within a transaction. If remove() is called on a detached entity, IllegalArgumentException will be thrown.
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).
EntityManager#remove()
works only on entities which are managed in the current transaction/context. In your case, you're retrieving the entity in an earlier transaction, storing it in the HTTP session and then attempting to remove it in a different transaction/context. This just won't work.
You need to check if the entity is managed by EntityManager#contains()
and if not, then make it managed it EntityManager#merge()
.
Basically, the delete()
method of your business service class should look like this:
em.remove(em.contains(entity) ? entity : em.merge(entity));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With