Java – the correct way to automatically connect hibernate session in spring transaction JUnit test
This problem is similar to the previous one I tried to @ autowire a hibernate session in my spring JUnit transaction test, but I got this exception:
java. Lang. IllegalStateException: no hibernate session is bound to a thread, and the configuration does not allow the creation of non transactional sessions
This is my JUnit class:
@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,"me@here.com"); } }
If I @ autowire a sessionfactory and get my sessions programmatically (instead of defining it in spring XML), each will work properly:
@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,"me@here.com"); } }
However, if I define my session in my spring XML using < AOP: scoped proxy / >, I can make my original example work like this:
<?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>
My question is: why does < AOP: scoped proxy / > need to consider that there should be only one thread limited transaction context in unit testing? What is the correct way to define my hibernate session bean?
Solution
SessionFactoryUtils. Getsession () is as good as any other way to get a session It does the same thing hibernatedaosupport Getsession() will do
The reason you need a scope proxy is because of timing There is no scope agent, it seems to inject the session before the test starts, so before the transaction starts, so you get an error
By adding a scope agent, it agent the session and inject, so it will not inject the actual session before the transaction starts, but just extract it and call it after the test run. When it actually needs to make an objection to it