我有一个带有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>
`
答案 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 :(得分: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上下文中,我对根包进行了上下文组件扫描,包括服务层,这就是为什么我最终得到非事务性服务的原因。