Spring @Transactional在部署到JBoss 7.1.1时不起作用

时间:2014-05-22 12:12:54

标签: spring hibernate jpa jboss transactions

我有一个带有Hibernate 4.0.1的Spring 3.2.8应用程序作为JPA实现。该应用程序应该部署在JBoss 7.1.1上,但到目前为止我还没有管理这些交易。

当我使用Spring集成测试加载上下文时,一切正常:

  • @ActiveProfiles(“dev-local-test”)使用内存数据库,运行正常

  • @ActiveProfiles(“dev-local”)直接连接到Oracle数据库,运行正常

  • 在部署到JBoss时,我也尝试使用“dev-local”配置文件,除了事务之外,一切正常。为了实现这一点,我重命名了persistence.xml,以便JBOSS的JPA引擎在Spring上下文初始化之前不会加载持久性单元,所以我明确地添加了org.hibernate依赖项。此外,这仍然使用JpaTransactionManager

  • 接下来,我尝试了另外两种服务器部署变体:

  • profile“dev-server1” - 仍然使用Spring org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean,但这次数据源是从JEE容器获取的,而TransactionManager是相同的,即JTA < / p>

  • profile“dev-server-2” - 其中EntityManagerFactory和JTA事务管理器都是从JEE容器中获取的,这次我提供了persistence.xml:

<persistence-unit name="app"> <jta-data-source>java:jboss/datasources/AppDS</jta-data-source> <properties> <property name="hibernate.show_sql" value="true"/> <property name="jboss.entity.manager.factory.jndi.name" value="java:/example/EntityManagerFactory"/> <property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup"/> <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/> </properties> </persistence-unit>

无论如何,在JBoss上部署时,事务都不起作用。在所有情况下我都没有得到任何异常(好吧,除了Hibernate lazy init,因为没有事务) 有人知道到目前为止我尝试过的所有配置有什么问题吗?

提前致谢, 亚历

`

<beans profile="dev-local, dev-local-test"> 
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="appDataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.my.project.domain</value>
            </list>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <!-- Need this because a bug in Hibernate 4.0.1 on JBoss 7.1.1 -->
                <prop key="hibernate.listeners.envers.autoRegister">false</prop>
            </props>
        </property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
</beans>

<beans profile="dev-local-test">
    <jdbc:embedded-database id="appDataSource">
        <jdbc:script location="sql/schema.sql" />
    </jdbc:embedded-database>
</beans>

<beans profile="dev-local">
    <context:property-placeholder location="classpath:/config/db-dev.properties" />
    <bean id="appDataSource" class="org.apache.commons.dbcp2.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${app.jdbc.driverClassName}" />
        <property name="url" value="${app.jdbc.url}" />
        <property name="username" value="${app.jdbc.username}" />
        <property name="password" value="${app.jdbc.password}" />
    </bean>
</beans>

<beans profile="dev-server-1">
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="appDataSource" />
        <property name="packagesToScan">
            <list>
                <value>com.my.project.domain</value>
            </list>
        </property>
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <!-- Need this because a bug in Hibernate 4.0.1 on JBoss 7.1.1 -->
                <prop key="hibernate.listeners.envers.autoRegister">false</prop>
            </props>
        </property>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
    </bean>

    <jee:jndi-lookup id="appDataSource" jndi-name="java:jboss/datasources/AppDS"
        expected-type="javax.sql.DataSource" />
    <tx:jta-transaction-manager id="transactionManager" />
</beans>

<beans profile="dev-server-2">
    <jee:jndi-lookup id="entityManagerFactory" jndi-name="java:/example/EntityManagerFactory" 
        expected-type="javax.persistence.EntityManagerFactory"/>
    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManagerName" value="java:/TransactionManager"/>
    </bean>
</beans>

`

4 个答案:

答案 0 :(得分:1)

Spring JtaTransactionManager只是一个外观,如果你想利用JBoss JTA / XA支持,你还需要配置特定的应用服务器事务管理器。

<bean id="jbossTransactionManager" class="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple">
</bean>

<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManager">
        <ref bean="jbossTransactionManager"></ref>
    </property>
</bean>

请检查this tutorial

Hibernate 4也引入了jta平台属性:

<property name="hibernate.transaction.jta.platform"
                  value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/>

<property name="hibernate.transaction.jta.platform"
                  value="org.hibernate.service.jta.platform.internal.JBossStandAloneJtaPlatform"/>

根据您使用JBoss AS的方式尝试其中一种。此属性应替换为:

  1. hibernate.transaction.manager_lookup_class属性
  2. hibernate.transaction.factory_class

答案 1 :(得分:1)

您忘了在persistence.xml中为persistence-unit指定transaction-type为JTA:

<persistence-unit name="app" transaction-type="JTA">

据我所知,如果你没有指定一个,你应该在Jboss设置中设置它。同时检查this answer

答案 2 :(得分:0)

在JBoss JNDI树中配置普通的非XA数据源(通过管理员UI或XML配置),一起删除persistence.xml,仅使用LocalContainerEntityManagerFactoryBean和包扫描以及JpaTransactionManager,从Spring配置中删除所有JTA内容JNDI查找JBoss提供的数据源,然后查看会发生什么。

我还要检查JBoss是否提供了Hibernate和/或Spring的冲突版本(如果你自己将它们捆绑在WEB-INF / lib中)。

答案 3 :(得分:0)

经过几个小时尝试不同的东西,结果证明原因很常见,根本与JBoss无关。

我有两个主要的Spring上下文文件,一个用于ROOT,另一个用于调度程序servlet。在调度程序servlet上下文中,我对根包进行了上下文组件扫描,包括服务层,这就是为什么我最终得到非事务性服务的原因。