4

我有一个 Java EE 应用程序,它使用 Hibernate 4.2.7 作为持久性提供程序,在可嵌入的 Websphere 8.0.0 容器中执行 Junit 测试。数据库访问在真实(即非嵌入式)Websphere 8.0.0 实例中工作正常。当使用 OpenJPA 而不是 Hibernate 运行时,单元测试确实有效。但是,使用 Hibernate 运行 Junit 测试时,出现以下异常:

CNTR0020E: 在对 bean“BeanId(embeddable#classes#SomeBean, null)”调用方法“getEntity”期间,EJB 引发了意外的(未声明的)异常。异常数据:org.hibernate.service.jndi.JndiException:无法查找 JNDI 名称 [java:comp/websphere/ExtendedJTATransaction]
    在 org.hibernate.service.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:68)
    在 org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:156)
    在 org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter$TransactionAdapter.(WebSphereExtendedJtaPlatform.java:152)
    在 org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getTransaction(WebSphereExtendedJtaPlatform.java:124)
    在 org.hibernate.service.jta.platform.internal.WebSphereExtendedJtaPlatform$TransactionManagerAdapter.getStatus(WebSphereExtendedJtaPlatform.java:119)
    在 org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:73)
    在 org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:115)
    在 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 内的类路径中。

我们的 persistence.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>

有人对此有解决方案吗?谢谢!

4

1 回答 1

0

交易策略配置

Hibernate 需要配置两个基本部分才能正确运行事务。第一个,hibernate.transaction.factory_class,定义了事务控制,第二个,hibernate.transaction.manager_lookup_class,定义了事务同步的注册机制,因此当持久化管理器需要与数据库同步更改时,它会在事务结束时得到通知。对于事务控制,支持容器管理和 bean 管理的配置。将 Hibernate 与 WebSphere Application Server 一起使用时,必须在 Hibernate.cfg.xml 中设置以下属性:

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 >

jta.UserTransaction 属性将工厂类配置为从 WebSphere 容器获取 UserTransaction 对象实例的实例。

在 WebSphere 平台上,WebSphere Application Server V6.x 和更高版本以及 WebSphere Business Integration Server Foundation V5.1 和更高版本都支持 hibernate.transaction.manager_lookup_class 属性。该属性将 Hibernate 配置为使用在 WebSphere Business Integration Server Foundation V5.1 和 WebSphere Application Server V6.0 中引入的 ExtendedJTATransaction 接口。WebSphere ExtendedJTATransaction 接口建立了一种模式,该模式通过 JTA 1.1 规范在 Java EE 5 中形式化。

于 2015-05-18T14:57:20.683 回答