java - Hibernate 在 emddable websphere 容器中找不到 java :comp/websphere/ExtendedJTATransaction

标签 java hibernate junit websphere embeddable

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

CNTR0020E: EJB threw an unexpected (non-declared) exception during invocation of method "getEntity" on bean "BeanId(embeddable#classes#SomeBean, null)". Exception data: org.hibernate.service.jndi.JndiException: Unable to lookup 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)
    ... stripped ...

It seems the implementation of WebsphereExtendedJtaPlatform is trying to get the current transaction via a JNDI lookup but fails because that JNDI name does not exist in the embedded container. Here's a snipped from 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>

有人有解决办法吗? 谢谢!

最佳答案

交易策略配置

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 Application Server V6.x 和更高版本以及 WebSphere Business Integration Server Foundation V5.1 和更高版本支持 hibernate.transaction.manager_lookup_class 属性。此属性将 Hibernate 配置为使用 ExtendedJTATransaction 接口(interface),该接口(interface)在 WebSphere Business Integration Server Foundation V5.1 和 WebSphere Application Server V6.0 中引入。 WebSphere ExtendedJTATransaction 接口(interface)建立了一种模式,该模式通过 JTA 1.1 规范在 Java EE 5 中形式化。

关于java - Hibernate 在 emddable websphere 容器中找不到 java :comp/websphere/ExtendedJTATransaction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27012870/

相关文章:

java - Standalone hibernate 和 narayana JTA 独立平台

java - Mockito 中未调用模拟方法

java - Spring Junit Hibernate @Transactional - 无 session

java - Java 中的内存分配 - Android

java - jmxagent 在添加到 Camel 上下文中时抛出 saxparse 异常

java - JSP(Java): Encoding byte array and use in JavaScript same in C#

java - 如何扫描SQL文件在数据库中创建表?

java - Spring boot 1.5.6 - 记录垃圾收集 Activity

java - Jackson + Hibernate = 很多问题

java - 如何在java中模拟Session对象