JTA经理是否需要在hibernate 4中使用事务功能

时间:2013-08-08 20:29:00

标签: spring hibernate tomcat7

我在这里关注教程: http://www.javacodegeeks.com/2013/05/hibernate-4-with-spring.html 在我的Java Web应用程序中启用“@Transactional注释”但未能使其正常运行。请告知JTA经理是否真的需要,为什么?

请注意,我的webapp基于Spring 3 + Hibernate 4 + Tomcat 7。

背景和我的怀疑:

我当前的Web应用程序使用我自己的自定义类(实现HandlerInterceptor)来启用one-hibernatesession-per-request。现在我想通过使用“@Transactional annotation”改进我的应用程序的可维护性,因为这可以节省许多代码行。

根据我的理解,@ Transactal基本上依赖于AOP概念来确保会话(Hibernate会话)准备好在带注释的方法中使用。这似乎与JTA无关。但我想知道为什么我不能在Tomcat 7中使用我的webapp(没有JTA-provider)。

在Google上进行少量搜索后,看起来似乎需要JTA。这让我感到困惑,因为这似乎是一个非常基本的功能,不应该将复杂的JTA提供者作为一项要求。

这是我得到的错误:

org.hibernate.HibernateException: No Session found for current thread
    org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:988)
    ...

这是我用于测试的代码:

....

@Autowired
org.hibernate.SessionFactory sessionFactory;

@Transactional
@RequestMapping(method = RequestMethod.GET)
protected String home() {
    Session session = sessionFactory.getCurrentSession(); // I expected the session is good to use now
    Province p = (Province) session.get(Province.class, 1L); // This causes no session found error :(


    return "home";
}

spring XML:

....
<tx:annotation-driven/>
<context:component-scan base-package="..."/>

<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/..."/>
    <property name="lookupOnStartup" value="true"/>
    <property name="proxyInterface" value="javax.sql.DataSource"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">update</prop>

            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
....

谢谢!

2 个答案:

答案 0 :(得分:0)

只是猜测:

您的控制器是在某种dispatcher-servlet.xml中定义的,因此与applicationContext分开,其中&lt; TX:注解驱动/&GT;被定义为。要使用@Transactional增强的组件需要与&lt; TX:注解驱动&GT;如果我没有弄错的话。所以@Transactional不起作用。

答案 1 :(得分:0)

这是我的愚蠢错误。 Spring使用CGLIB来代理带有@Transactional注释的方法,似乎CBLIB不能增强受保护的方法。

protected String home() {

将此更改为

public String home() {

修复了问题。