web-dev-qa-db-fra.com

java.lang.IllegalArgumentException: suppression d'une instance détachée com.test.User # 5

J'ai un projet Java EE utilisant JPA (transaction-type = "JTA"), hibernate en tant que fournisseur. J'écris mes haricots pour gérer les choses CRUD. Le programme exécuté dans JBOSS 7 AS.

J'ai un 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);
    }
}

mais lorsque j'invoque deleteObject, cette exception se produit.

Java.lang.IllegalArgumentException: suppression d'une instance détachée com.test.User # 5

Comment cela est-il causé et comment puis-je le résoudre?

43
neptune

EntityManager#remove() ne fonctionne que sur les entités gérées dans la transaction/le contexte en cours. Dans votre cas, vous récupérez l'entité dans une transaction antérieure, la stockez dans la session HTTP, puis essayez de la supprimer dans une transaction/un contexte différent. Cela ne marchera pas.

Vous devez vérifier si l'entité est gérée par EntityManager#contains() et si ce n'est pas le cas, faites-la alors gérer/ EntityManager#merge() .

En gros, la méthode delete() de votre classe de services métier devrait ressembler à ceci:

em.remove(em.contains(entity) ? entity : em.merge(entity));
177
BalusC

Dans mon cas, j'ai eu la même erreur, quand j'ai essayé de supprimer un objet .__ en utilisant, 

session.delete(obj)

sans créer de transaction avant cela.

Et le problème est résolu en créant d'abord la transaction (session.beginTransaction ()), puis en supprimant l'objet.

J'espère que ma réponse aidera quelqu'un :)

3
Rajesh

Parfois, c'est simplement parce qu'il vous manque l'annotation @Transaction pour les opérations d'ajout, suppression et mise à jour.

0
Lingying Zhang

J'ai rencontré le même problème. L'entité détachée doit être rattachée. Comme @BalusC l'a mentionné, l'utilisation de EntityManager.merge() devrait être utilisée pour attacher l'entité détachée. EntityManager.merge() génère une requête SQL qui récupère l'état actuel de l'entité sur laquelle EntityManager.remove() doit être exécuté. Mais dans mon cas, cela n'a pas fonctionné. Essayez EntityManager.remove(EntityManager.find(Class<T>,arg)) à la place. Cela a fonctionné pour moi.

0
murali101002

D'après mon expérience, si j'interroge un objet de la base de données puis ferme le gestionnaire d'entités, puis supprime une base de données, le problème se produit. Ou si je copie cet objet chargé dans une autre instance, puis effectue une suppression, ce problème se produit également . À mon avis, il y a 2 choses à garder à noter:

  • L'objet doit appartenir à la même session créée par Entity Manager.
  • Et l'objet ne doit pas être transféré vers un autre objet tant que la session du gestionnaire d'entités est toujours ouverte.

À votre santé

0
Artanis Zeratul