I'm trying to use a StatelessSession to do some bulk inserts in an OSGi environment (Karaf 4.0.7), but when I try to commit my transaction I get
I don't use JTA for managing my transactions, I set hibernate.transaction.coordinator_class=jdbc. The code that uses a regular Sesssion runs fine. There's another portion of the application that runs in a non-OSGi environment, and there the StatelessSession works fine. I tracked it down into the Hibernate source and found in org.hibernate.internal.StatelessSessionImpl :
@Override
public void flushBeforeTransactionCompletion() {
boolean flush = false;
try {
flush = (
!isClosed()
&& !isFlushModeNever()
&& !JtaStatusHelper.isRollback(
getJtaPlatform().getCurrentStatus()
) );
}
catch (SystemException se) {
throw new HibernateException( "could not determine transaction status in beforeCompletion()", se );
}
if ( flush ) {
managedFlush();
}
}
Since the session isn't closed, and StatelessSessionImpl.isFlushModeNever() always returns false, the method getJtaPlatform() always gets called, which ultimately fails because it can find a JtaPlatform (org.hibernate.osgi.OsgiJtaPlatform), but the OsgiJtaPlatform can't find a TransactionManager. When I install the Karaf feature "transaction", which installs an OSGi Transaction Manager (provided by Apache Aries), the Exception is no longer thrown and everything is committed fine. However, it seems silly that I have to install a JTA component for using StatelessSession, while I don't use JTA Transactions. In the non-OSGi portion of the application, which runs in Tomcat, I found in the debug logs :
So there Hibernate uses org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform. In the karaf log, I found the properties with which the SessionFactory is instantiated :
I tried setting the jta platform to NoJtaPlatform by adding to hibernate.properties : hibernate.transaction.jta.platform=org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform But this had no effect : it still logged that the session factory was created using OsgiJtaPlatform. Is there a way to make Hibernate use the NoJtaPlatform when it's running in an OSGi container ? I'm using Hibernate 5.2.17. This approach worked fine in Hibernate 4.3.7 by the way, but then there was no hibernate-osgi bundle, and it seems the StatelessSessionImpl class has undergone some significant changes. I posted this on the Hibernate discussion : https://discourse.hibernate.org/t/can-you-use-a-hibernate-5-2-statelesssession-in-an-osgi-environment-like-karaf-without-the-use-of-jta/1303 There it was suggested a to file a Bug report. |