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
