I encountered something very similar a while back. In my case I'm using PAX
JDBC to create the pooled DataSource via config admin. Like you I found
that data was being committed within the transaction lambda.

I determined that this didn't happen with XA DataSources.

I resolved this by providing my own DBCP Pooled Data Source Factory that
declared itself as supporting XA. I don't recall the details of exactly why
I had to do this  - it was 5 years ago and past me decided not to comment
this.

I'm using Karaf 4.1.1 & Java 8. The PAX data source is provided to JPA via
persistence.xml via the jta-data-source element & a JNDI lookup.

Anyway - try making your DS XA and see if that changes anything.

On Wed, 28 Jun 2023 at 18:59, Ash Williams <[email protected]> wrote:

> 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
>
>
> [image: 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
>
> 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