Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Hi,

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Hi Piero,

Sorry to only get to this email chain now.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically
create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is
described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to

Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration
entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)

Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending
on which implementation you choose and you need to specify:

Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved
in a big fight over who is supposed to be controlling what.

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of
a warning sign that things might not be correct.

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.

So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all. You don’t
provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely different
transactions than are being set up by the Transaction Control runtime.

I’m assuming that you didn’t read the JavaDoc
for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider, and made sure
that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate is looking
for a transaction using Java EE and finds nothing.

Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and this should
all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the necessary plugins
to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the DataSourceFactory
and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically
create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is
described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to

Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration
entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)

Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending
on which implementation you choose and you need to specify:

Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved
in a big fight over who is supposed to be controlling what.

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of
a warning sign that things might not be correct.

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.

So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all. You don’t
provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely different
transactions than are being set up by the Transaction Control runtime.

I’m assuming that you didn’t read the JavaDoc
for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider, and made sure
that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate is looking
for a transaction using Java EE and finds nothing.

Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and this should
all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the necessary plugins
to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the DataSourceFactory
and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Hi,

That is substantial progress - the first error you are seeing is in the Aries Transaction Control logic for detecting which plugin it should try to deploy into the JPA provider. This requires version 1.1 of the OSGi JPA service (which added the
getPersistenceProviderName() method to EntityManagerFactoryBuilder) to work. Now the Transaction Control implementation correctly imports the JPA spec package at [1.1,2) which means that the issue is that the JPA service implementation that you’re using claims
to be supporting version 1.1, but actually isn’t. I can’t see the Aries JPA container (the reference implementation of the v1.1 JPA Service) deployed in your bundles, which bundle are you using to provide the JPA service?

The second error appears to be a bug in Karaf’s processing of configurations, and probably needs to be reported there.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically
create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is
described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to

Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration
entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)

Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending
on which implementation you choose and you need to specify:

Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved
in a big fight over who is supposed to be controlling what.

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of
a warning sign that things might not be correct.

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.

So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all.
You don’t provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely
different transactions than are being set up by the Transaction Control runtime.

I’m assuming that you didn’t read
the JavaDoc for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider,
and made sure that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate
is looking for a transaction using Java EE and finds nothing.

Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and
this should all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the
necessary plugins to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the
DataSourceFactory and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.

Re: Not resolved Provider using TransactionControl and JPAEntityManagerProvider

Tim,

many thanks again for your advices.

Definitely it seemed to be a version conflict problem (as almost every problem in OSGi....).

Karaf 4.2.0 comes with a not too updated version of Eclipselink and it brings a version 2.6.1 of the Apache Aries JPA Container adapter for EclipseLink.

I unistalled it and installed the last version of Aries Tx Ctrl with the JPA Container adapter Ver. 2.7.1-SNAPSHOT, and now it works.

I am performing some test for massive data loading, with different granularity of transactions, nested tx, noRollback exceptions etc... and it seems to be a comfortable choice for a big project I'm carry on.

Unfortunally I have still some hang session updating the test bundle in Karaf, often with losing of the JPAEntityManagerProvider that appears again only after a lot of attempts, but I will submit the question to Karaf community, as you suggested. So for now, many thanks for your help.

That is substantial progress - the first error you are seeing is in the Aries Transaction Control logic for detecting which plugin it should try to deploy into the JPA provider. This requires version 1.1 of the OSGi JPA service (which added the
getPersistenceProviderName() method to EntityManagerFactoryBuilder) to work. Now the Transaction Control implementation correctly imports the JPA spec package at [1.1,2) which means that the issue is that the JPA service implementation that you’re using claims
to be supporting version 1.1, but actually isn’t. I can’t see the Aries JPA container (the reference implementation of the v1.1 JPA Service) deployed in your bundles, which bundle are you using to provide the JPA service?

The second error appears to be a bug in Karaf’s processing of configurations, and probably needs to be reported there.

Firstly, the behaviour that you’re seeing (no JPAEntityManagerProvider registered, but a JPAEntityManagerProviderFactory is registered) is correct. The Factory service is a generic service that is always registered and can be used to programatically
create your managed EntityManager transactional resource. A JPAEntityManagerProvider service is registered only if you set one up as a Configuration Driven Resource. This creates the Provider for you based on a configuration in Configuration Admin, and is
described in the documentation pages.

<tldr>

If you want to use Transaction Control then there is a lot of conflicting and misconfigured stuff going on in your example. The simplest thing to do is to

Make sure that your persistence unit does not specify any Database configuration (this should always come from outside the bundle, whether you’re using Transaction Control or not). Specifically delete the datasource JNDI name and property configuration
entries from the persistence.xml. Unless you are using Hibernate Specific annotations you should also remove the persistence provider entry (yes, an empty persistence unit is a good thing!)

Create a Configuration Driven Resource by adding a factory configuration for the relevant pid (local transactions look like they would work fine for you, but stick with XA if you really want). The factory pid is org.apache.aries.tx.control.jpa.local or org.apache.aries.tx.control.jpa.xa depending
on which implementation you choose and you need to specify:

Inject the JPAEntityManagerProvider service like you did previously. It will be there and you can use it, but make sure your transaction control is injected first (the references get sorted into alphabetical order by bnd!).

Secondly, I see that you’re having problems with setting up the transactionality of your EntityManager, and that you’re using XA transactions. This is most likely because the bundles and configurations that you have in your runtime are involved
in a big fight over who is supposed to be controlling what.

This is a second transaction management API with a separate transaction manager. Transactions that are started/integrated with this will be entirely separate from the ones in transaction control, so having these bundles present is something of
a warning sign that things might not be correct.

This is a secondary layer of pooling that is likely to interfere with attempts to enlist in transactions. Transaction Control already provides pooling so this is at best redundant, and at worst going to break things.

So what you’re doing here is creating an XA enabled DataSource which Karaf is going to enlist with a transaction manager service. This will *definitely* fight with the Transaction Control implementation, which does not use this mechanism at all.
You don’t provide your persistence.xml, but at a guess you’re using a JTA Datasource with a JNDI name pointing at the DataSource service you’ve just created here. As I’ve mentioned, this will mean that the DataSource you’re using is trying to look for completely
different transactions than are being set up by the Transaction Control runtime.

I’m assuming that you didn’t read
the JavaDoc for this particular method? Using an EntityManagerFactory directly with the JPAEntityManagerProviderFactory is a very strong statement about how much you have set up. You are expected to have registered all of the plugins for your provider,
and made sure that the correct DataSource transactions are set up. It very much looks like you haven’t done this, and this is almost certainly the reason that you’re getting the TransactionRequiredException out of the EntityManager (specifically because Hibernate
is looking for a transaction using Java EE and finds nothing.

Fixing all this is actually not too hard. The simplest thing to do is to use a configuration driven resource (described up top). Persistence units should not, in general, define anything about the database connections that they want to use, and
this should all be driven by configuration admin. Failing that, if you want to use the JPAEntityManagerProviderFactory service then you should be using the version that takes an EntityManagerFactoryBuilder, not an EntityManagerFactory. This will apply the
necessary plugins to link Hibernate into the Transaction Control managed transaction. Transaction Control should be able to unwrap the Karaf datasource sufficiently to access the raw XADataSource, but if that isn’t possible you will also want to inject the
DataSourceFactory and to create the XADataSource yourself, passing it in as part of the configuration map.

I would strongly recommend the configuration driven option as the simpler way to go.

Digging some deeper in the environment, I saw that it exists a bundle (ID=84) that should provide the missing service, so I cannot understand why this service does not result suitable for other bundles:

I would like to receive some help about a non resolving provider service in a very simple test bundle I wrote to test TransactionControl with JPAEntityManagerProvider usage with Hibernate on Karaf 4.2.

The core of the program is a "DAO Service" and both interface and implementation are reported below.