我有一个Java EE应用程序,它使用Hibernate 4.2.7作为持久性提供程序,在可嵌入的Websphere 8.0.0容器中执行Junit测试。数据库访问在真实(即非嵌入式)Websphere 8.0.0 实例中工作正常。单元测试在使用 OpenJPA 而不是休眠时确实有效。但是,使用 Hibernate 运行 Junit 测试时,我得到以下异常:
CNTR0020E:EJB 在调用 bean 上的方法 "getEntity" "BeanId(embeddable#classes#SomeBean, null)"时抛出了一个意外的(未声明的)异常。Exception data: org.hibernate.service.jndi.JndiException: 无法查找 JNDI name [java:comp/websphere/ExtendedJTATransaction] at org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:156) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:152) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getTransaction(WebSphereExtendedJtaPlatform.java:124) at org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getStatus(WebSphereExtendedJtaPlatform.java:119) at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73) at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115) at org.hibernate.service.jta.platform.internal.TransactionManagerBasedSynchronizationStrategy.canRegisterSynchronization(TransactionManagerBasedSynchronizationStrategy.java:56) ...剥夺。。。
WebsphereExtendedJtaPlatform 的实现似乎试图通过 JNDI 查找获取当前事务,但失败了,因为嵌入式容器中不存在该 JNDI 名称。以下是从org.hibernate.service.jta.platform.internal.WebsphereExtendedJtaPlatform截取
的片段:
public class TransactionAdapter implements Transaction {
private TransactionAdapter() {
if ( extendedJTATransaction == null ) {
extendedJTATransaction = jndiService().locate( "java:comp/websphere/ExtendedJTATransaction" );
}
}
... stripped ...
类 ExtendedJtaTransaction 本身确实存在于 com.ibm.ws.runtime.jar 中的类路径上。
我们的持久性.xml中的设置如下所示:
<persistence-unit name="BLA" transaction-type="JTA">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/BLA</jta-data-source>
<class>com.some.Entity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
<property name="hibernate.archive.autodetection" value="class" />
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup" />
<property name="jta.UserTransaction" value="java:comp/UserTransaction" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="hibernate.jdbc.fetch_size" value="100" />
<property name="hibernate.temp.use_jdbc_metadata_defaults" value="false" />
</properties>
有人对此有解决方案吗?谢谢!
交易策略配置
Hibernate需要配置两个基本部分才能正确运行事务。第一个(hibernate.transaction.factory_class)定义事务控制,第二个hibernate.transaction.manager_lookup_class定义事务同步的注册机制,以便在事务结束时通知持久性管理器,当它需要与数据库同步更改时。对于事务控制,同时支持容器管理的配置和 Bean 管理的配置。将 Hibernate 与 WebSphere Application Server 配合使用时.cfg.xml必须在 Hibernate 中设置以下属性:
for container-managed transactions:
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.CMTTransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
</property>
for bean-managed transactions:
<property name="hibernate.transaction.factory_class">
org.hibernate.transaction.JTATransactionFactory
</property>
<property name="hibernate.transaction.manager_lookup_class">
org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
</property>
<property name="jta.UserTransaction">
java:comp/UserTransaction
</property >
日报.UserTransaction 属性将工厂类配置为从 WebSphere 容器中获取 UserTransaction 对象实例的实例。
WebSphere Application Server V6.x 及更高版本在 WebSphere 平台上以及 WebSphere Business Integration Server Foundation V5.1 及更高版本支持 hibernate.transaction.manager_lookup_class 属性。此属性将 Hibernate 配置为使用 ExtendedJTATransaction 接口,该接口在 WebSphere Business Integration Server Foundation V5.1 和 WebSphere Application Server V6.0 中引入。WebSphere ExtendedJTATransaction 接口建立了一个模式,该模式通过 JTA 1.1 规范在 Java EE 5 中形式化。