i try to make declarative transaction work.
This is my spring.xml file:
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="jdbc:h2:tcp://my/db/path" />
<property name="username" value="username" />
<property name="password" value="password" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="data" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<context:component-scan base-package="test" />
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
And this is my controller implementation:
//file TestController.java
public interface TestController {
public List<Test> findAll();
}
//file TestControllerImp.java
@Controller
public class TestControllerImp implements TestController{
@Autowired
private SessionFactory sessionFactory;
/**
* @return the sessionFactory
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
/**
* @param sessionFactory the sessionFactory to set
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory=sessionFactory;
}
@Transactional
public List<Test> findAll() {
return sessionFactory.getCurrentSession().createQuery("from Test").list();
}
}
Both are inside package called test.
This is my try:
TestController tc=context.getBean(TestController.class);
List<Test> list=tc.findAll();
But this throw an exception:
org.hibernate.HibernateException: createQuery is not valid without active transaction
Why transactionManager doesn't work? I hope with @Transactional annotation all transactions will be managed by spring framework. What can i do?
Thanks all.
Remove the following lines, they are not needed when transactions are managed by Spring:
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
Actually, setting hibernate.current_session_context_class
effectively disables Spring transaction management, see AbstractSessionFactoryBean.setExposeTransactionAwareSessionFactory()
javadoc:
Turn this flag off to expose the plain Hibernate SessionFactory with Hibernate's default getCurrentSession() behavior, supporting plain JTA synchronization only. Alternatively, simply override the corresponding Hibernate property "hibernate.current_session_context_class".
I seem to recall that you can get odd behavior with stereotype-annotated classes like your @Controller
, when the class implements an interface like this.
I'm not 100% sure what the workaround for this, but try one or both of the following:
@Transactional
from TestControllerImp.findAll()
to TestController.findAll()
proxy-target-class="true"
to your <tx:annotation-driven/>
One or both or those should do the trick, but neither is ideal. I've seen this before in other questions, and never quite got to the bottom of what's causing it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With