Je suppose que la réponse est : cela dépend .
Votre gestionnaire d'entités est la clé pour accéder au contexte où résident les entités. Si votre application est une application JSE, vous devez vous demander quelle est la durée de vie de votre contexte.
Considérons que vous allez créer un gestionnaire d'entités à la demande d'un utilisateur. Ainsi, pendant que vous vous occupez d'une demande donnée, vous gardez votre gestionnaire d'entités ouvert, et lorsque vous avez terminé, vous le fermez.
Dans une application JSE, vous avez peut-être envisagé de garder votre gestionnaire d'entités ouvert pendant toute la durée de vie de l'application (en supposant que vous ne traitiez pas de grandes quantités de données), puis de le fermer lorsque votre application s'arrête.
En fin de compte, le moment où vous l'ouvrez et celui où vous le fermez dépend entièrement de votre stratégie et de votre conception. Vous la fermez lorsque vous n'avez plus besoin des entités dans leur contexte.
Dans votre exemple, ce n'est pas évident, mais puisque vous créez l'EM dans la méthode, vous devriez le fermer avant de revenir, sinon vous n'y aurez plus accès (à moins que vous ne le conserviez dans un registre, ce qui n'est pas évident dans le code).
Si vous ne la fermez pas, vos entités resteront attachées, même après que vous ayez fini de les utiliser. Votre contexte sera maintenu en vie même si vous ne pouvez plus accéder à votre EM.
El Spécification JPA contient plus de détails. Dans la section 7.7 Contextes de persistance gérés par l'application il est dit :
Lorsqu'un gestionnaire d'entités géré par l'application est utilisé, l'application interagit directement avec l'usine du gestionnaire d'entités du fournisseur de persistance du fournisseur de persistance pour gérer le cycle de vie du gestionnaire d'entités et pour obtenir et détruire les contextes de persistance.
Tous ces contextes de persistance gérés par l'application sont étendus dans l'application étendue, et peuvent couvrir plusieurs transactions.
El EntityManagerFactory.createEntityManager
et la méthode EntityManager
close
y isOpen
sont utilisées pour gérer les cycle de vie d'un gestionnaire d'entités géré par une application et de son contexte de contexte de persistance associé.
Le contexte de persistance étendu existe à partir du moment où l'élément gestionnaire d'entités a été créé à l'aide de EntityManagerFactory.createEntityManager
jusqu'à ce que le gestionnaire d'entités soit fermé au moyen de EntityManager.close
.
Un contexte de persistance étendu obtenu à partir du contexte de persistance géré par l'application d'entités géré par l'application est un contexte de persistance autonome, il n'est pas propagé avec la transaction.
[...] Le site EntityManager.close
ferme un gestionnaire d'entités pour libérer son contexte de persistance et ses autres ressources. Après avoir appelé close, l'application ne doit pas invoquer d'autres méthodes sur le gestionnaire d'entités. EntityManager
sauf pour getTransaction
y isOpen
ou le site IllegalStateException
seront lancés. Si la méthode de fermeture est est invoquée lorsqu'une transaction est active, le contexte de persistance reste géré géré jusqu'à la fin de la transaction.
El EntityManager.isOpen
indique si le gestionnaire d'entités est ouvert. Le site isOpen
retourne vrai jusqu'à ce que le gestionnaire d'entités ait a été fermé. Pour comprendre comment cela fonctionne, il est essentiel de comprendre la relation entre le gestionnaire d'entités et le contexte.
Ainsi, comme vous pouvez le constater, le gestionnaire d'entités est l'interface publique par laquelle vous accédez à vos entités. Cependant, vos entités résident dans un contexte, attaché à votre gestionnaire d'entités. La compréhension du cycle de vie des différents types de contextes répondra à votre question.
Les contextes de persistance peuvent être de différents types. Dans les applications Java EE, vous pouvez avoir soit un contexte de persistance de type transactionnel ou un contexte de persistance étendue . Dans l'application JSE, la nature du contexte est contrôlé par le développeur .
Lorsque vous demandez une entité à votre gestionnaire d'entités, il cherche l'entité dans le contexte qui lui est attaché, s'il trouve l'entité à cet endroit, il la renvoie, sinon, il récupère l'entité dans la base de données. Les appels ultérieurs pour cette entité dans le contexte retourneront la même entité.
Transaction-scoped
Dans une application Java EE utilisant le contexte de persistance à l'échelle de la transaction, lorsque vous accédez pour la première fois à votre gestionnaire d'entités, celui-ci vérifie si la transaction JTA actuelle possède un contexte attaché ; si aucun contexte n'est encore présent, un nouveau contexte est créé et le gestionnaire d'entités est lié à ce contexte. Ensuite, l'entité est lue depuis la base de données (ou depuis le cache s'il est présent) et elle est placée dans le contexte. Lorsque la transaction se termine (commit ou rollback), le contexte devient invalide et les entités qu'il contient sont détachées. C'est le scénario classique pour les sessions de beans sans état.
@PersistenceContext(unitName="EmplService")
EntityManager em;
Cela signifie également que, selon la façon dont vous concevez vos transactions, vous pouvez vous retrouver avec plus d'un contexte.
Contexte de persistance étendue
Dans une application Java EE avec des beans de session à état, vous voudrez peut-être que le contexte survive à de multiples invocations du bean, car vous n'aimeriez pas vous engager tant que le bean n'a pas été marqué pour être supprimé, n'est-ce pas ? Dans ce cas, vous devez utiliser un contexte de persistance étendu. Dans ce cas, le contexte de persistance est créé lorsqu'il est requis pour la première fois, mais il ne deviendra pas invalide tant que vous n'aurez pas marqué le bean à état pour le supprimer.
@PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED)
Cela signifie que, quelle que soit l'instance du gestionnaire d'entités qui est injectée dans ce bean lors des appels ultérieurs des méthodes des beans de session à état, vous pouvez être sûr que vous accéderez toujours au même contexte et que, par conséquent, même les appels ultérieurs renverront la même instance, car il s'agit du même contexte.
En outre, vos modifications ne seront pas supprimées tant que le haricot n'est pas marqué pour être supprimé ou que vous ne les supprimez pas manuellement.
Application-Managed
Vous pouvez toujours instancier manuellement votre fabrique de gestionnaire d'entités et votre gestionnaire d'entités. C'est ce que vous feriez typiquement dans une application JSE, n'est-ce pas ?
Pour ce type d'applications, vous ne disposez généralement pas d'un conteneur pour gérer les transactions JTA, n'est-ce pas ? Vous utilisez donc des transactions locales aux ressources et vous êtes responsable de l'acceptation ou du retrait manuel des changements.
Pour ce type d'application, lorsque vous instanciez votre gestionnaire d'entités, un contexte lui est automatiquement attaché.
En fonction de votre application, vous pouvez décider de créer un gestionnaire d'entités global dont le cycle de vie est attaché à la vie de l'application elle-même. C'est-à-dire un seul gestionnaire d'entités pour toute la durée de vie de l'application. Dans ce cas, votre contexte sera créé et détruit avec votre gestionnaire d'entités.
Ou bien, vous pouvez créer un gestionnaire d'entités par conversation (c'est-à-dire par transaction) avec l'utilisateur de votre application. Dans ce cas, c'est vous qui déterminez la portée, mais votre contexte sera tout de même créé et détruit avec votre gestionnaire d'entités.
0 votes
Duplicata possible de Dois-je fermer() chaque EntityManager ?
0 votes
Non, juste non. Sauf si tu veux des fuites...