我有一个 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/