Spring/Hibernate异常:没有活动事务,createCriteria无效。

9

我花了几天时间解决一个spring-hibernate-transaction的问题。我创建了一个简单的WebService,使用jaxws + spring + hibernate,它工作得很好,但是当我调用使用事务bean的Web方法时,Spring抛出了以下错误:

21 sept. 2011 14:29:29 com.sun.xml.ws.server.sei.EndpointMethodHandler invoke
GRAVE: org.hibernate.HibernateException: createCriteria is not valid without active transaction

我看起来交易已经开始了...但是出现了一些问题。

[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Creating new transaction with name [com.cellfish.mediadb.ws.encoder.MediaDBFeeds.testTransaction]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly; ''
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Opened new Session [org.hibernate.impl.SessionImpl@26b20a31] for Hibernate transaction
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@26b20a31]
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Exposing Hibernate transaction as JDBC transaction [jdbc:mysql://xxxxxxxx, MySQL-AB JDBC Driver]
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Found thread-bound Session [org.hibernate.impl.SessionImpl@26b20a31] for Hibernate transaction
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Participating in existing transaction
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Participating transaction failed - marking existing transaction as rollback-only
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Setting Hibernate transaction on Session [org.hibernate.impl.SessionImpl@26b20a31] rollback-only
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Initiating transaction rollback
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@26b20a31]
[jmedia] 21 sept. 2011 14:29:29 [http-8080-1] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager  - Closing Hibernate Session [org.hibernate.impl.SessionImpl@26b20a31] after transaction
21 sept. 2011 14:29:29 com.sun.xml.ws.server.sei.EndpointMethodHandler invoke

这是我的应用上下文:

<context:annotation-config/>

    <!-- List of packages managed by Spring -->
    <context:component-scan base-package="..." />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://xxxx"/>
        <property name="username" value="xxx"/>
        <property name="password" value="xxx"/>
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="packagesToScan" value="xxxx"/>
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager" />
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

以下是 hibernate.cfg.xml 文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <!-- a SessionFactory instance listed as /jndi/name -->
    <session-factory>

        <property name="dialect">org.hibernate.dialect.MySQLInnoDBDialect</property>
        <property name="show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.connection.pool_size">1</property>

        <property name="hibernate.jdbc.batch_size">20</property>
        <!-- Bind the getCurrentSession() method to the thread. -->
        <property name="current_session_context_class">thread</property>
        <property name="hibernate.cache.provider_class">net.sf.ehcache.hibernate.SingletonEhCacheProvider</property>
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <property name="hibernate.cache.use_query_cache">true</property>

        <!-- Lucene Search -->
        <property name="hibernate.search.default.directory_provider">org.hibernate.search.store.RAMDirectoryProvider</property>

    </session-factory>

我把这个Web应用部署在Tomcat6上。 希望您能帮助我解决这个问题。

谢谢。


你确定你的bean/method有@Transactional注解吗?并且同一个bean在Spring上下文中被调用和管理了吗? - Michael Pralow
是的,我的bean被@ Transactional注释,并由Spring管理。 - juliusdev
1个回答

26

好的,我找到问题所在了!我从Hibernate配置中删除了这一行。 Spring管理事务,并且不需要会话保持在Hibernate线程中。

<!-- Bind the getCurrentSession() method to the thread. -->
<property name="current_session_context_class">thread</property>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接