Cette question est semblable à une précédente one. Je suis en train de @Autowire
une session Hibernate dans l'un de mes tests printemps-JUnit-transactionnelles mais je reçois cette exception:Façon correcte d'autowire une session Hibernate dans un test JUnit de transaction de printemps
java.lang.IllegalStateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional ...
Voici ma classe JUnit:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
@TransactionConfiguration(transactionManager="transactionManager")
@Transactional
public class MyTest {
@Qualifier("session")
@Autowired
private Session session;
@Test
public void testSomething() {
session.get(User.class, "[email protected]");
}
}
Chaque fonctionne très bien si je @Autowire
un SessionFactory
et obtenir mon Session
programme (au lieu de le définir dans le code XML de printemps) comme ceci:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
@TransactionConfiguration(transactionManager="transactionManager")
@Transactional
public class MyTest{
@Qualifier("sessionFactory")
@Autowired
private SessionFactory sessionFactory;
@Test
public void testSomething() {
Session session = SessionFactoryUtils.getSession(sessionFactory, false);
session.get(User.class, "[email protected]");
}
}
je peux, cependant, obtenir mon exemple original de travailler si je définis mon Session
dans mon XML Spring avec <aop:scoped-proxy />
comme ceci:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
...
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation"><value>classpath:/hibernate.cfg.xml</value></property>
<property name="configurationClass">
<value>org.hibernate.cfg.AnnotationConfiguration</value>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="session" class="org.springframework.orm.hibernate3.SessionFactoryUtils" factory-method="getSession" scope="prototype">
<constructor-arg ref="sessionFactory" />
<constructor-arg value="false" />
<!-- This is seems to be needed to get rid of the 'No Hibernate Session' error' -->
<aop:scoped-proxy />
</bean>
</beans>
Ma question est: Pourquoi est-<aop:scoped-proxy />
nécessaire étant donné qu'il ne devrait un thread- contexte de transaction limitée dans mon test unitaire? Qu'est-ce que est la bonne façon de définir mon haricot Hibernate Session
? SessionFactoryUtils.getSession() est aussi bon que n'importe quel autre moyen d'obtenir la session
Merci pour la réponse. Si j'ai défini "allowCreate" sur true, Spring apparaît pour créer une deuxième session de base de données non transactionnelle, c'est-à-dire que l'annotation @Transactional n'annule pas mes modifications pendant le test. Le problème avec autowiring un HibernateTemplate est que j'ai des classes au niveau DAO qui dépendent de Session. Je suppose que je pourrais les faire dépendre de HibernateTemplate et ensuite faire un get (User.class ...) comme vous l'avez suggéré. Cependant, j'ai l'impression de violer la loi de Demeter, étant donné que la véritable dépendance de la classe DAO est Session et NOT HibernateTemplate. – 0sumgain
Vos DAO sont-ils injectés avec une session ou avec une SessionFactory? Si vous injectez une session, vous voudrez probablement la repenser, ce n'est probablement pas une bonne idée. – skaffman
DAO sont injectés avec Session. Pouvez-vous expliquer pourquoi ce n'est pas une bonne idée? Merci. – 0sumgain