是否可以在WAS Liberty Profile中使用Hibernate 5作为JPA引擎

时间:2017-01-26 11:07:55

标签: hibernate jpa websphere-liberty

我在我的Liberty项目中使用了4.3.11,但在版本5中解决了Hibernate的问题。我尝试过升级但是我得到了不同的例外。

有人正在使用Hibernate 5.x.x和Liberty Profile吗?您在server.xml的dataSource库中包含哪些jar?

感谢

4 个答案:

答案 0 :(得分:3)

如果我包含这些JAR,我已经能够让Hibernate 5.x至少部分在Liberty中工作:

  <library id="hibernate">
    <file name="${server.config.dir}/hibernate/antlr-2.7.7.jar"/>
    <file name="${server.config.dir}/hibernate/classmate-1.3.0.jar"/>
    <file name="${server.config.dir}/hibernate/dom4j-1.6.1.jar"/>
    <file name="${server.config.dir}/hibernate/hibernate-commons-annotations-5.0.1.Final.jar"/>
    <file name="${server.config.dir}/hibernate/hibernate-core-5.2.6.Final.jar"/>
    <file name="${server.config.dir}/hibernate/javassist-3.20.0-GA.jar"/>
    <file name="${server.config.dir}/hibernate/jboss-logging-3.3.0.Final.jar"/>
  </library>

  <application location="myApp.war">
    <classloader commonLibraryRef="hibernate"/>
  </application>

我说部分工作的原因是,如果使用非jta-data-source,它会很有效,但是当尝试使用jta-data-source时,Hibernate可能无法找到特定于供应商的API来暂停当前事务。 Hibernate确实有一些属性可以设置为告诉它它正被WebSphere服务器使用,并且我已经探索了那些没有jta-data-source成功结果的组合。我认为Hibernate实现缺乏对Liberty的意识,这是真正应该添加的东西,(如果你觉得它有价值的话,请参阅HHH-10388并投票支持它),尽管在它缺席的情况下你可以让它工作通过编写自己的Hibernate JtaPlatform实现,该实现委托给com.ibm.tx.jta.TransactionManagerFactory并将其指定为持久性属性。

例如在persistence.xml中,

  <persistence-unit ...
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    ...
    <properties>
      <property name="hibernate.transaction.jta.platform" 
                value="example.WebSphereLibertyJtaPlatform" />
    </properties>
  </persistence-unit>

示例实现,

package example;

import com.ibm.tx.jta.TransactionManagerFactory;
import javax.naming.*;
import javax.transaction.*;
import org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform;

public class WebSphereLibertyJtaPlatform implements JtaPlatform {
    public boolean canRegisterSynchronization() {
        try {
            return getCurrentStatus() == Status.STATUS_ACTIVE;
        } catch (SystemException x) {
            throw new RuntimeException(x);
        }
    }

    public int getCurrentStatus() throws SystemException {
        return retrieveTransactionManager().getStatus();
    }

    public Object getTransactionIdentifier(Transaction transaction) {
        return transaction;
    }

    public void registerSynchronization(Synchronization synchronization) {
        try {
            retrieveTransactionManager().getTransaction().registerSynchronization(synchronization);
        } catch (IllegalStateException x) {
            throw new RuntimeException(x);
        } catch (RollbackException x) {
            throw new RuntimeException(x);
        } catch (SystemException x) {
            throw new RuntimeException(x);
        }
    }

    public TransactionManager retrieveTransactionManager() {
        return TransactionManagerFactory.getTransactionManager();
    }

    public UserTransaction retrieveUserTransaction() {
        try {
            return InitialContext.doLookup("java:comp/UserTransaction");
        } catch (NamingException x) {
            throw new RuntimeException(x);
        }
    }
}

答案 1 :(得分:1)

即使我最终遇到了类似的情况。 异常消息是:com.ibm.ws.container.service.state.StateChangeException:javax.xml.stream.FactoryConfigurationError:无法实例化提供程序javax.xml.stream.XMLEventFactory:java.util.ServiceConfigurationError:javax.xml。 stream.XMLEventFactory:找不到提供者com.ibm.xml.xlxp2.api.stax.XMLEventFactoryImpl

你看到有什么突破吗?

答案 2 :(得分:1)

我知道线程有点旧,但比较Liberty Profile 17.0.0.2和17.0.0.3我注意到他们已经介绍了这个类

com.ibm.ws.jpa.hibernate.LibertyJtaPlatform

现在当我启动应用服务器时,容器会在调用时传递一些属性

HibernatePersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties)

为数据源初始化hibernate,在属性中初始化你拥有该类的实例:

enter image description here

希望它有所帮助。

答案 3 :(得分:0)

从Hibernate 5.2.13开始,为Liberty提供了正确的事务集成。如果您能够升级到此版本的Hibernate,则会自动检测并应用它,而不必再指定hibernate.transaction.jta.platform

有关详细信息,请参阅此Hibernate问题:https://hibernate.atlassian.net/browse/HHH-11571