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
.
Les deux implémentations fournissent un modèle de programmation de type "une session - une transaction à la base de données",
aussi connu sous le nom de session-per-request. Le début et la fin d'une session Hibernate sont définis par la durée d'une transaction de base de données. Si vous utilisez
une démarcation programmatique de la transaction (par exemple sous J2SE ou JTA/UserTransaction/BMT), nous vous conseillons
d'utiliser l'API Hibernate Transaction
pour masquer le système de transaction utilisé. Si vous exécutez sous un conteneur EJB qui supporte CMT, vous n'avez besoin
d'aucune opérations de démarcations de session ou transaction dans votre code puisque tout est géré de manière déclarative.
Référez vous à Chapitre 11, Transactions et accès concurrents pour plus d'informations et des exemples de code.
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".