Hi,

We have an issue where sql statements executed by hibernate are being 
immediately committed, despite the fact that the entity manager is managed by a 
(local) transaction. It's my understanding that hibernate and the transaction 
manager should together ensure that auto commit is disabled on the obtained 
connection. My environment is Karaf 4.4.3 on Java 8 and hibernate 5.6.7.

# Here is the persistence.xml file:

<persistence>
  <persistence-unit name="acme.pu" transaction-type="JTA" />
</persistence>

# Here is a self-contained class that demonstrates the problem:

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.sql.DataSource;

import org.apache.commons.lang3.RandomStringUtils;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.jdbc.DataSourceFactory;
import org.osgi.service.jpa.EntityManagerFactoryBuilder;
import org.osgi.service.transaction.control.TransactionControl;
import org.osgi.service.transaction.control.jdbc.JDBCConnectionProviderFactory;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProvider;
import org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory;

@Component(immediate = true)
public class AcmeTest {

   @Activate
   public AcmeTest(

      @Reference(target = "(osgi.unit.name=acme.pu)")
         EntityManagerFactoryBuilder emfb,

      @Reference(target = 
"(&(osgi.jdbc.driver.name=oracle)(osgi.jdbc.driver.class=oracle.jdbc.OracleDriver))")
         DataSourceFactory dsf,

      @Reference(target = "(osgi.local.enabled=true)")
         JPAEntityManagerProviderFactory providerFactory,

      @Reference(target = "(osgi.local.enabled=true)")
         TransactionControl txControl

   ) throws IOException, SQLException {

      // create datasource from factory

      Properties dsfProps = new Properties();
      dsfProps.put("user", "xxx-withheld-xxx");
      dsfProps.put("password", "xxx-withheld-xxx");
      dsfProps.put("url", "xxx-withheld-xxx");

      DataSource datasource = dsf.createDataSource(dsfProps);

      // create jpa entity manager provider from datasource and pool props

      Map<String, Object> jpaProperties = new HashMap<>();
      jpaProperties.put("javax.persistence.dataSource", datasource);
      jpaProperties.put("hibernate.dialect", 
"org.hibernate.dialect.Oracle10gDialect");

      Map<String, Object> resourceProviderProperties = new HashMap<>();
      
resourceProviderProperties.put(JDBCConnectionProviderFactory.CONNECTION_POOLING_ENABLED,
 false);

      JPAEntityManagerProvider provider = providerFactory.getProviderFor(emfb, 
jpaProperties, resourceProviderProperties);

      // test it out by updating a test_column to a random string

      EntityManager entityManager = provider.getResource(txControl);
      txControl.required(() -> {

         String newValue = RandomStringUtils.random(10, true, false);

         Query query = entityManager.createNativeQuery("update test_table set 
test_column = ? where test_name = 'test'");
         query.setParameter(1, newValue);

         query.executeUpdate();

         // ***************************************************************
                              // CONNECTION HAS BEEN COMMITTED SINCE WE CAN SEE 
UPDATED VALUE OF
                              // TEST_COLUMN IN THE DATABASE WHILST WE ARE 
STILL IN THIS LAMBDA
         // ***************************************************************

         return null;

      });

   }

}

# This information about the transaction services running on the platform might 
be important:

admin@root()> bundle:services -p 281

pax-transx-tm-geronimo (281) provides:
--------------------------------------
objectClass = [org.osgi.service.cm.ManagedService]
service.bundleid = 281
service.id = 335
service.pid = org.ops4j.pax.transx.tm.geronimo
service.scope = singleton
----
objectClass = [javax.transaction.TransactionManager, 
javax.transaction.TransactionSynchronizationRegistry, 
javax.transaction.UserTransaction, 
org.apache.geronimo.transaction.manager.RecoverableTransactionManage
r, org.springframework.transaction.PlatformTransactionManager]
service.bundleid = 281
service.id = 360
service.scope = singleton
----
objectClass = [org.ops4j.pax.transx.tm.TransactionManager]
service.bundleid = 281
service.id = 376
service.scope = singleton




admin@root()> bundle:services -p 298

OSGi Transaction Control JPA Resource Provider - Local Transactions (298) 
provides:
-----------------------------------------------------------------------------------
objectClass = 
[org.osgi.service.transaction.control.jpa.JPAEntityManagerProviderFactory]
osgi.local.enabled = true
service.bundleid = 298
service.id = 312
service.scope = bundle
----
objectClass = [org.osgi.service.cm.ManagedServiceFactory]
service.bundleid = 298
service.id = 313
service.pid = org.apache.aries.tx.control.jpa.local
service.scope = singleton

Thanks
Ash



[EDW Technology]<https://www.teamenergy.com/>
EDW Technology Ltd
3 Radian Court, Knowlhill, Milton Keynes MK5 8PJ, United Kingdom
+44 (0)844 880 2489 | www.edwt.org<https://www.edwt.org>

Energy Auditing Agency Limited (TEAM) registered in England and Wales, number 
01916768. Registered office 3 Radian Court, Knowlhill, Milton Keynes MK5 8PJ. 
This electronic message contains information which may be privileged or 
confidential. The information is intended for the use of the individual(s) or 
organisation named. If you are not the intended recipient please be aware that 
any disclosure, copying, distribution or use of the contents of this 
information is prohibited. If you have received this electronic message in 
error, please delete this e-mail from your system and notify us by replying to 
this email immediately.

Reply via email to