Esta pregunta es similar a una one anterior. Estoy tratando de @Autowire
una sesión de Hibernate en una de mis pruebas Primavera-JUnit-transaccional pero yo estoy haciendo esta excepción:Forma correcta de autoautar una sesión de Hibernate en una prueba de la JUnit de la transacción de primavera
java.lang.IllegalStateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional ...
Aquí es mi clase 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]");
}
}
Cada funciona bien si @Autowire
un SessionFactory
y obtener mi Session
programación (en lugar de definirlo en el XML de primavera), así:
@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]");
}
}
Puedo, sin embargo, tener en mis original ejemplo a trabajar si defino mi Session
en mi XML primavera con <aop:scoped-proxy />
así:
<?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>
Mi pregunta es: ¿Por qué se <aop:scoped-proxy />
necesario dado que sólo debe uno thread- contexto de transacción limitado en mi prueba de unidad? ¿Qué es la forma correcta de definir mi Hibernate Session
frijol?
Gracias por la respuesta. Si configuro "allowCreate" como verdadero, Spring parece crear una segunda sesión de base de datos no transaccional, es decir, la anotación @Transactional no revierte mis cambios durante la prueba. El problema con el autoenvío de un HibernateTemplate es que tengo clases de nivel DAO que dependen de Session. Supongo que podría hacer que dependieran de HibernateTemplate y luego hacer un get (User.class ...) como sugirieron. Sin embargo, creo que estoy violando la Ley de Demeter, dado que la verdadera dependencia de la clase DAO es Session y NO HibernateTemplate. – 0sumgain
¿Sus DAO se inyectan con una sesión o con una SessionFactory? Si está inyectando una sesión, probablemente quiera reconsiderar eso, probablemente no sea una buena idea. – skaffman
Los DAO se inyectan con Session. ¿Puedes explicar por qué esa no es una buena idea? Gracias. – 0sumgain