Certaines applications utilisant Hibernate ont besoin d'une sorte de session "contextuelle", où une session est liée à la
portée d'un contexte particulier. Cependant, les applications ne définissent pas toutes la notion de contexte de la même manière,
et différents contextes définissent différentes portées à la notion de "courant". Les applications à base d'Hibernate, versions
précédentes à la 3.0 utilisaient généralement un principe maison de sessions contextuelles basées sur le ThreadLocal
, ainsi que sur des classes utilitaires comme HibernateUtil
, ou utilisaient des framework tiers (comme Spring ou Pico) qui fournissaient des sessions contextuelles basées sur l'utilisation
de proxy/interception.
A partir de la version 3.0.1, Hibernate a ajouté la méthode SessionFactory.getCurrentSession()
. Initialement, cela demandait l'usage de transactions JTA
, où la transaction JTA
définissait la portée et le contexte de la session courante. L'équipe Hibernate pense que, étant donnée la maturité des implémentations
de JTA TransactionManager
, la plupart (sinon toutes) des applications devraient utiliser la gestion des transactions par JTA
qu'elles soient ou non déployées dans un conteneur J2EE
. Par conséquent, vous devriez toujours contextualiser vos sessions, si vous en avez besoin, via la méthode basée sur JTA.
Cependant, depuis la version 3.1, la logique derrière SessionFactory.getCurrentSession()
est désormais branchable. A cette fin, une nouvelle interface d'extension (org.hibernate.context.CurrentSessionContext
) et un nouveau paramètre de configuration (hibernate.current_session_context_class
) ont été ajoutés pour permettre de configurer d'autres moyens de définir la portée et le contexte des sessions courantes.
Allez voir les Javadocs de l'interface org.hibernate.context.CurrentSessionContext
pour une description détaillée de son contrat. Elle définit une seule méthode, currentSession()
, depuis laquelle l'implémentation est responsable de traquer la session courante du contexte. Hibernate fournit deux implémentation
de cette interface.
org.hibernate.context.JTASessionContext
- les sessions courantes sont associées à une transaction JTA
. La logique est la même que l'ancienne approche basée sur JTA. Voir les javadocs pour les détails.
org.hibernate.context.ThreadLocalSessionContext
- les sessions courantes sont associées au thread d'exécution. Voir les javadocs pour les détails.
org.hibernate.context.ManagedSessionContext
- current sessions are tracked by thread of execution. However, you are responsible to bind and unbind a Session
instance with static methods on this class, it does never open, flush, or close a Session
.
The first two implementations provide a "one session - one database transaction" programming model, also known and used as
session-per-request. The beginning and end of a Hibernate session is defined by the duration of a database transaction. If you use programmatic
transaction demarcation in plain JSE without JTA, you are advised to use the Hibernate Transaction
API to hide the underlying transaction system from your code. If you use JTA, use the JTA interfaces to demarcate transactions.
If you execute in an EJB container that supports CMT, transaction boundaries are defined declaratively and you don't need
any transaction or session demarcation operations in your code. Refer to Chapitre 11, Transactions et accès concurrents for more information and code examples.
Le paramètre de configuration hibernate.current_session_context_class
définit quelle implémentation de org.hibernate.context.CurrentSessionContext
doit être utilisée. Notez que pour assurer la compatibilité avec les versions précédentes, si ce paramètre n'est pas défini
mais qu'un org.hibernate.transaction.TransactionManagerLookup
est configuré, Hibernate utilisera le org.hibernate.context.JTASessionContext
. La valeur de ce paramètre devrait juste nommer la classe d'implémentation à utiliser, pour les deux implémentations fournies,
il y a cependant deux alias correspondant: "jta" et "thread".