2015-10-25 2 views
3

J'utilise Spring 4.2.1 et Hiberante 5 et maintenant essayer de comprendre comment la session du printemps initialise déclaré dans les grains de printemps Définition comme suit:session Comprendre hibernent Initialisation

<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 
    <!-- properties --> 
</bean> 

Je trouve que ce qu'on appelle org.springframework.orm.hibernate5.LocalSessionFactoryBean implémente FactoryBean<SessionFactory>. Taking this into account il est clair pourquoi nous définissons la définition SessionFactory à injecter avec la classe org.springframework.orm.hibernate5.LocalSessionFactoryBean, mais se retrouvent avec l'instance de SessionFactory. Maintenant, ce que je confondais par est la méthode getCurrentSession:

public Session getCurrentSession() throws HibernateException { 
    if (currentSessionContext == null) { 
     throw new HibernateException("No CurrentSessionContext configured!"); 
    } 
    return currentSessionContext.currentSession(); 
} 

qui délègue la création de session réelle au SpringSessionContext et dans mon cas, il est en cours de récupération par ce piece of code:

SessionHolder sessionHolder = (SessionHolder) value; 
Session session = sessionHolder.getSession(); 

Mais le session est en fait une instance de org.hibernate.internal.SessionImpl la classe de base directe org.hibernate.internal.AbstractSessionImpl dont elle-même a la propriété protected transient SessionFactoryImpl factory.

Ainsi, le SessionFactory a la propriété CurrentSessionContext qui dans mon cas contient SessionHolder qui à son tour contient l'instance réelle Session. Mais le SessionImpl a de nouveau une propriété du type SessionFactory.

Je ne comprends pas la circulaire. Ne pourriez-vous pas l'expliquer un peu?

Répondre

1

Eh bien, la mise en œuvre de printemps CurrentSessionContext ne tient pas SessionHolder, au lieu Sessionholder est récupéré à chaque fois que cette méthode currentSession est invoquée. Voir ceci:

Object value = TransactionSynchronizationManager.getResource(this.sessionFactory); 
... 
SessionHolder sessionHolder = (SessionHolder) value; 

Donc, dans votre cas on injecte certaines implémentations, mais il peut être un autre en cas de configuration différente.

Je pense que le but principal de cette conception est d'avoir une bonne séparation des préoccupations. L'objectif principal du SessionContext est de relier le gestionnaire de transactions et le détenteur de session pour vous fournir une session bien configurée en fonction de la configuration de la transaction.

Il existe d'autres implémentations de CurrentSessionContext, je crois que Hibernate a au moins trois implémentations, donc le scénario que vous avez décrit dépend de la configuration du ressort qui injecte de telles classes.

Comme les États Javadoc:

mise en œuvre CurrentSessionContext peut également être spécifié dans la configuration SessionFactory personnalisée à travers le "hibernate.current_session_context_class"

+0

Oui, en effet, vous êtes tout à fait raison. J'ai découvert que 'TransactionSynchronizationManager' a un champ' private ThreaLocal' statique appelé 'resources'. Et la liaison réelle du 'SessionHolder' est effectuée en enveloppant l'intance de la Session dans le support en tant que nouveau SessionHolder (session), puis en liant avec la clé' sessionFactory'. Mais il est encore un peu difficile de comprendre comment la circularité permet la séparation des préoccupations .... –