我有一个 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>
有人对此有解决方案吗?谢谢!