We have been using the included OpenJPA implementation in the EJB3 feature pack for WebSphere 6.1.0.19. Because of some limitations, we wish to use Hibernate EntityManager as a persistence provider instead. Our environment consists of the following:
Hibernate EntityManager version: 3.3.2.GA
Hibernate version: 3.2.6.ga
Hibernate Annotations version: 3.3.1.GA
WebSphere version:6.1.0.19 + EJB3 Feature Pack
Our project is built with Maven, and we use the existing maven artifacts for those. These artifacts and their dependencies are included in the generated EAR. We exclude the "ejb3-persistence" artifact explicitly, because this is provided by the server. On the WebSphere server, the class loader order is modified from "parent-first" to "child-first". (Basically, we followed the official WebSphere documentation on using an external persistence provider.) In the logs, we see that the Hibernate JPA provider is effectively in use.
We use the following settings in the persistence.xml configuration file:
Code:
<persistence-unit name="test_unit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jta-data-source>jdbc/Database</jta-data-source>
<non-jta-data-source>jdbc/DatabaseNonJTA</non-jta-data-source>
<class>org.test.AnEntity</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.InformixDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.transaction.factory_class"
value="org.hibernate.transaction.CMTTransactionFactory"/>
<property name="hibernate.transaction.manager_lookup_class"
value="org.hibernate.transaction.WebSphereExtendedJTATransactionLookup"/>
</properties>
</persistence-unit>
We want to use container-managed transactions. The relevant settings in the configuration are factory_class and manager_lookup_class. These properties are configured as found in documentation by people from IBM:
Using Spring and Hibernate with WebSphere Application Server. Also documentation on the Hibernate site itselfs confirms this. See the section "Transaction demarcation with EJB/CMT" on the following page:
Sessions and transactions.
However, when using this configuration, we get the following warning when Hibernate processes the configuration: "org.hibernate.ejb.Ejb3Configuration prepareProperties Overriding hibernate.transaction.factory_class is dangerous, this might break the EJB3 specification implementation". If we just ignore this, and run our tests, we get another warning: "AbstractEntit W org.hibernate.ejb.AbstractEntityManagerImpl joinTransaction
Cannot join transaction: do not override hibernate.transaction.factory_class". It seems that read-only access to the database succeeds, but updates silently fail. We only get the warning.
Since the warning advises to not override the factory_class, and in addition, other documentation of hibernate explicitly states that factory_class should be set by hibernate itself (see
section 4.2.2 Using JTA), and thus cannot be set manually, we dropped this from the configuration file. Still, this does not seem to give correct behaviour.
In one of our tests, we get an "OptimisticLockException". It seems that Hibernate wants to do a rollback, but we get the following exception:
Code:
AbstractEntit E org.hibernate.ejb.AbstractEntityManagerImpl throw PersistenceException
Unable to mark for rollback on PersistenceException:
java.lang.UnsupportedOperationException
at org.hibernate.transaction.WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.setRollbackOnly(WebSphereExtendedJTATransactionLookup.java:103)
at org.hibernate.ejb.AbstractEntityManagerImpl.markAsRollback(AbstractEntityManagerImpl.java:440)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:595)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:608)
at org.hibernate.ejb.AbstractEntityManagerImpl.merge(AbstractEntityManagerImpl.java:244)
at com.ibm.ws.jpa.management.JPAExEmInvocation.merge(JPAExEmInvocation.java:336)
at com.ibm.ws.jpa.management.JPAEntityManager.merge(JPAEntityManager.java:122)
...
When looking at the code for WebSphereExtendedJTATransactionLookup, it seems like most of the methods result in an UnsupportedOperationException. Is this normal or is the implementation of this class simply not complete?
Can anyone help with the correct settings for using Hibernate as JPA persistence provider in WebSphere, with container-managed transactions using JTA?
Any help greatly appreciated,
Ruben