60 votes

Détacher une entité du contexte de persistance JPA/EJB3

Quel serait le moyen le plus simple de détacher un Bean d'entité JPA spécifique qui a été acquis par le biais d'un EntityManager. Ou encore, pourrais-je faire en sorte qu'une requête renvoie des objets détachés dès le départ, afin qu'ils agissent essentiellement en "lecture seule" ?

La raison pour laquelle je veux faire cela est que je veux modifier les données à l'intérieur du bean - dans mon application seulement, mais sans jamais les faire persister dans la base de données. Dans mon programme, je dois éventuellement appeler flush() sur l'EntityManager, qui persisterait toutes les modifications des entités attachées à la base de données sous-jacente, mais je veux exclure des objets spécifiques.

62voto

(il est peut-être trop tard pour répondre, mais cela peut être utile pour d'autres)

Je suis en train de développer mon premier système avec JPA. Malheureusement, je suis confronté à ce problème alors que ce système est presque terminé.

En clair. Utilisez Hibernate, ou attendez JPA 2.0.

Dans Hibernate, vous pouvez utiliser 'session.evict(object)' pour supprimer un objet de la session. Dans JPA 2.0, en cours d'élaboration , il existe la méthode "EntityManager.detach(object)" pour détacher un objet du contexte de persistance.

29voto

Heidarzadeh Points 2152

Quelle que soit l'implémentation de JPA que vous utilisez, utilisez simplement entityManager.detach(object) il est maintenant dans JPA 2.0 et fait partie de JEE6.

19voto

James McMahon Points 14356

Si vous avez besoin de détacher un objet de l'EntityManager et que vous utilisez Hibernate comme couche ORM sous-jacente, vous pouvez avoir accès à l'élément suivant Session Hibernate et utiliser l'objet Session.evict(Objet) que Mauricio Kanada a mentionné ci-dessus.

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

Bien sûr, cela ne fonctionnerait pas si vous passiez à un autre fournisseur ORM, mais je pense qu'il est préférable d'essayer de faire une copie profonde.

17voto

Andrei Points 556

Malheureusement, il n'y a aucun moyen de déconnecter un objet du gestionnaire d'entités dans l'implémentation actuelle de JPA, AFAIR.

EntityManager.clear() va se déconnecter. tous les objets JPA, ce qui peut ne pas être une solution appropriée dans tous les cas, si vous avez d'autres objets que vous prévoyez de garder connectés.

Le mieux serait donc de cloner les objets et de transmettre les clones au code qui modifie les objets. Comme les champs d'objets primitifs et immuables sont pris en charge par le mécanisme de clonage par défaut de manière appropriée, vous n'aurez pas à écrire beaucoup de code de plomberie (à part le clonage profond de toute structure agrégée que vous pourriez avoir).

3voto

James Points 18355

Si vous utilisez EclipseLink, vous disposez également des options suivantes,

Utilisez l'indice de requête "eclipselink.maintain-cache"="false" - tous les objets renvoyés seront détachés.

Utilisez l'API EclipseLink JpaEntityManager copy() pour copier l'objet à la profondeur souhaitée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X