69 votes

Injection de Vs EntityManager EntityManagerFactory

Une longue question, s'il vous plaît garder avec moi.

Nous sommes à l'aide de Printemps+JPA pour une application web. Mon équipe est de débattre sur l'injection EntityManagerFactory dans la GenericDAO (DAO basé sur les médicaments Génériques quelque chose sur les lignes fournies par APPFUSE, nous n'utilisons pas d' JpaDaosupport pour une certaine raison) sur l'injection d'un EntityManager. Nous sommes à l'aide de l'application "managed persistence".

Les arguments contre l'injection d'un EntityManagerFactory , c'est que c'est trop lourd et n'est donc pas nécessaire, l' EntityManager fait ce dont nous avons besoin. Aussi, alors que le Printemps serait de créer une nouvelle instance d'un DAO pour chaque requête web(j'en doute) il n'y a pas de problèmes de concurrence que dans le même EntityManager instance est partagée par les deux threads.

L'argument de l'injection de l'EFM est que c'est une bonne pratique sur l'ensemble de son toujours bon d'avoir une poignée à l'usine.

Je ne suis pas sûr de ce qui est la meilleure approche, quelqu'un peut-il svp m'éclairer?

51voto

skaffman Points 197885

Les avantages et les inconvénients de l'injection de EntityManagerFactory vs EntityManager sont tous énoncés dans le Ressort de docs ici, je ne suis pas sûr si je peux l'améliorer.

En disant cela, il ya quelques points dans votre question qui doit être éclairci.

...Printemps de créer une nouvelle instance de un DAO pour chaque requête web...

Ce n'est pas correct. Si votre DAO est un Ressort de haricots, puis c'est un singleton, à moins que vous le configurer autrement par l'entremise de l' scope attribut du bean définition. L'instanciation d'un DAO pour chaque demande, ce serait de la folie.

L'argument de l'injection de l'EFM est que c'est une bonne pratique sur l'ensemble de son toujours bon d'avoir une poignée pour un usine.

Cet argument n'est pas vraiment en tenir à l'eau. Les bonnes pratiques en général dit qu'un objet doit être injecté avec le minimum de collaborateurs il a besoin pour faire son travail.

25voto

SB. Points 702

Je suis en train de monter vers le bas ce que j'ai enfin réunis...

Bien que EntityManagerFactory instances sont thread-safe, EntityManager instances ne sont pas. L'injection de l'EntityManager se comporte comme un EntityManager récupérée à partir d'un serveur d'application de l'environnement JNDI, tel que défini par la spécification JPA. Il délégués de tous les appels à l'actuelle transactionnelle EntityManager, le cas échéant; sinon, il tombe de retour pour une nouvelle EntityManager par opération, en effet de rendre son utilisation de thread-safe. -- À Partir Du Printemps De Référence

Cela signifie que par JPA spécifications EntityManager instances ne sont pas thread-safe, mais si le Printemps poignées eux, ils sont thread-safe.


Si vous utilisez du Printemps, il est préférable d'injecter EntityManagers au lieu de EntityManagerFactory.


9voto

James McMahon Points 14356

Je pense que cela a déjà été bien couvert, mais juste pour renforcer quelques points.

  • Le DAO, si elle est injectée par le Printemps, est un singleton par défaut. Vous devez définir explicitement le champ d'application de prototype pour créer une nouvelle instance à chaque fois.

  • L'entité crèche injecté par @PersistenceContext est thread-safe.

Cela étant dit, j'ai eu quelques problèmes avec un singleton DAO dans mon application multi-thread. J'ai fini par faire de la DAO un instanciées bean et qui a résolu le problème. Ainsi, alors que la documentation peut dire une chose, vous voulez probablement pour tester votre application en profondeur.

Suivi:

Je pense qu'une partie de mon problème est que je suis en utilisant

@PersistenceContext(unitName = "unit",
    type = PersistenceContextType.EXTENDED)

Si vous utilisez PersistenceContextType.ÉTENDU, gardez à l'esprit que vous devez, si je comprends bien, fermez manuellement la transaction. Voir ce fil pour plus d'informations.

Un autre de son Suivi:

À l'aide d'un instanciées DAO est une très mauvaise idée. Chaque instance de la DAO avoir sa propre persistance du cache et des changements à un cache ne sera pas reconnu par les autres DAO haricots. Désolé pour les mauvais conseils.

6voto

Gaël Marziou Points 914

J'ai constaté que définir l'annotation @Repository Spring sur nos DAO et avoir EntityManager géré par Spring et injecté par l'annotation @PersistenceContext est le moyen le plus pratique de tout faire fonctionner correctement. Vous bénéficiez de la sécurité des threads d'EntityManager partagé et de la traduction des exceptions. Par défaut, EntityManager partagé gérera les transactions si vous combinez plusieurs DAO à partir d'un gestionnaire, par exemple. En fin de compte, vous constaterez que vos DAO deviendront anémiques.

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