Is it possible to use Hibernate 5 as JPA engine in WAS Liberty Profile

前端 未结 4 1742
故里飘歌
故里飘歌 2021-01-23 10:58

I use 4.3.11 in my Liberty projects but there is a bug with Hibernate solved in version 5. I have tried upgrading but I get different exceptions.

Anybody is using Hibern

相关标签:
4条回答
  • 2021-01-23 11:15

    As of Hibernate 5.2.13, a proper transaction integration has been delivered for Liberty. If you are able to upgrade to this version of Hibernate, then it will be detected and applied automatically, and not necessary to specify hibernate.transaction.jta.platform anymore.

    See this Hibernate issue for more details: https://hibernate.atlassian.net/browse/HHH-11571

    0 讨论(0)
  • 2021-01-23 11:24

    Even i ended up with similar situation. The exception message was: com.ibm.ws.container.service.state.StateChangeException: javax.xml.stream.FactoryConfigurationError: Provider javax.xml.stream.XMLEventFactory could not be instantiated: java.util.ServiceConfigurationError: javax.xml.stream.XMLEventFactory: Provider com.ibm.xml.xlxp2.api.stax.XMLEventFactoryImpl not found

    do you see any break through?

    0 讨论(0)
  • 2021-01-23 11:34

    I've been able to get Hibernate 5.x at least partially working in Liberty if I include these JARs:

      <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>
    

    The reason I say partially working is that it works great if using non-jta-data-source, but when trying to use jta-data-source, Hibernate can fail trying to locate vendor-specific API to suspend the current transaction. Hibernate does have some properties that you can set to tell it that it's being used by WebSphere servers, and I've explored various combinations of those without a successful outcome for jta-data-source. I think the Hibernate implementation is lacking in its awareness of Liberty, which is something that really ought to be added, (see HHH-10388 and vote for it if you would find it valuable) although in its absence you can get it working by writing your own implementation of Hibernate JtaPlatform that delegates to com.ibm.tx.jta.TransactionManagerFactory and specifying it as a persistence property.

    For example in persistence.xml,

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

    Example implementation,

    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);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-23 11:41

    I know the thread is a bit old, but comparing Liberty Profile 17.0.0.2 and 17.0.0.3 I have noticed they have introduced this class

    com.ibm.ws.jpa.hibernate.LibertyJtaPlatform
    

    and now when I start the app server, the container passes some properties when calls

    HibernatePersistenceProvider.createContainerEntityManagerFactory(PersistenceUnitInfo info, Map properties)
    

    to initialize hibernate for a data-source and in the properties you have the instance of that class:

    Hope it helps.

    0 讨论(0)
提交回复
热议问题