MariaDB/JPA Transaction rollback not working

classic Classic list List threaded Threaded
37 messages Options
12
Reply | Threaded
Open this post in threaded view
|

MariaDB/JPA Transaction rollback not working

Alex Soto
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):


<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
        <feature>pax-jdbc-config</feature>
         <feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>

My Data Source is configured in the file org.ops4j.datasource-responder.cfg

osgi.jdbc.driver.name = mariadb
dataSourceName=responder
url = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false

user=XXXX
password=XXXX
databaseName=responder

#Pool Config
pool=dbcp2
xa=true

My persistence.xml:

<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
    
    <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        
        <!-- Only used when transaction-type=JTA -->
        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
        
        <!-- Only used when transaction-type=RESOURCE_LOCAL -->
        <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
        
        <properties>
            <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="none"/>
        </properties>
    </persistence-unit>
</persistence>

My blueprint.xml:


<jpa:enable />
<tx:enable />

<bean id="userService" class="org.data.impl.UserServiceImpl" />
<service ref="userService" interface="org.data.UserService" />

</blueprint>

For testing I throw exception in my DAO:

@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}

I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.

Best regards,
Alex soto




Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

jbonofre
Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:

> With Karaf version 4.2.0, Rollback is not working with MariaDB
> and InnoDB tables.
> I deployed these features (from Karaf’s enterprise  repository):
>
>
> <feature>aries-blueprint</feature>
> <feature>transaction</feature>
> <feature>jndi</feature>
> <feature>jdbc</feature>
> <feature>jpa</feature>
> <feature>pax-jdbc-mariadb</feature>
>          <feature>pax-jdbc-config</feature>
> <feature>pax-jdbc-pool-dbcp2</feature>
> <feature>hibernate</feature>
>
> My Data Source is configured in the file
> /org.ops4j.datasource-responder.cfg/
>
>     osgi.jdbc.driver.name = mariadb
>     dataSourceName=responder
>     url
>     = jdbc:mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
>
>     user=XXXX
>     password=XXXX
>     databaseName=responder
>
>     #Pool Config
>     pool=dbcp2
>     xa=true
>
>
> My persistence.xml:
>
>     <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
>          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>          xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>     http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
>      
>        <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
>          
>        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>              <!-- Only used when transaction-type=JTA -->
>          
>        <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
>              <!-- Only used when transaction-type=RESOURCE_LOCAL -->
>          
>        <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
>              <properties>
>              
>        <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
>                  <property name="hibernate.show_sql" value="true" />
>                  <property name="hibernate.format_sql" value="true" />
>                  <property name="hibernate.hbm2ddl.auto" value="none"/>
>              </properties>
>          </persistence-unit>
>     </persistence>
>
>
> My blueprint.xml:
>
>     <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>     xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>     xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
>     https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
>
>     <jpa:enable />
>     <tx:enable />
>
>     <bean id="userService" class="org.data.impl.UserServiceImpl" />
>     <service ref="userService" interface="org.data.UserService" />
>
>     </blueprint>
>
>
> For testing I throw exception in my DAO:
>
> @Transactional(REQUIRED)
> public void addUser(User user) {
> em.persist(user);
> em.flush();
> throw new RuntimeException("On Purpose");
> }
>
> I expect the record not to be in the table due to rollback of the
> transaction, but it still shows up in my database table.
>
> Best regards,
> Alex soto
>
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.

Best regards,
Alex soto




On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email]> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
        <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
   osgi.jdbc.driver.name = mariadb
   dataSourceName=responder
   url
   = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
   user=XXXX
   password=XXXX
   databaseName=responder
   #Pool Config
   pool=dbcp2
   xa=true
My persistence.xml:
   <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
   http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
            <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
            <!-- Only used when transaction-type=JTA -->
                <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
            <!-- Only used when transaction-type=RESOURCE_LOCAL -->
                <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
            <properties>
                    <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
                <property name="hibernate.hbm2ddl.auto" value="none"/>
            </properties>
        </persistence-unit>
   </persistence>
My blueprint.xml:
   <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
   xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
   https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
   <jpa:enable />
   <tx:enable />
   <bean id="userService" class="org.data.impl.UserServiceImpl" />
   <service ref="userService" interface="org.data.UserService" />
   </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto

Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

jbonofre
Are you sure about your code ? Flush looks weird to me and it seems you
don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:

> Yes, same result.  I even tried with Narayana Transaction Manager, and
> same result.
>
> Best regards,
> Alex soto
>
>
>
>
>> On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> Same behavior with RequiresNew ?
>>
>> Regards
>> JB
>>
>> On 16/05/2018 19:44, Alex Soto wrote:
>>> With Karaf version 4.2.0, Rollback is not working with MariaDB
>>> and InnoDB tables.
>>> I deployed these features (from Karaf’s enterprise  repository):
>>> <feature>aries-blueprint</feature>
>>> <feature>transaction</feature>
>>> <feature>jndi</feature>
>>> <feature>jdbc</feature>
>>> <feature>jpa</feature>
>>> <feature>pax-jdbc-mariadb</feature>
>>>         <feature>pax-jdbc-config</feature>
>>> <feature>pax-jdbc-pool-dbcp2</feature>
>>> <feature>hibernate</feature>
>>> My Data Source is configured in the file
>>> /org.ops4j.datasource-responder.cfg/
>>>    osgi.jdbc.driver.name = mariadb
>>>    dataSourceName=responder
>>>    url
>>>    = jdbc:mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
>>>    user=XXXX
>>>    password=XXXX
>>>    databaseName=responder
>>>    #Pool Config
>>>    pool=dbcp2
>>>    xa=true
>>> My persistence.xml:
>>>    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
>>>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>>> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
>>>             <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
>>>                 <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>>>             <!-- Only used when transaction-type=JTA -->
>>>                 <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
>>>             <!-- Only used when transaction-type=RESOURCE_LOCAL -->
>>>                 <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
>>>             <properties>
>>>                     <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
>>>                 <property name="hibernate.show_sql" value="true" />
>>>                 <property name="hibernate.format_sql" value="true" />
>>>                 <property name="hibernate.hbm2ddl.auto" value="none"/>
>>>             </properties>
>>>         </persistence-unit>
>>>    </persistence>
>>> My blueprint.xml:
>>>    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>>>    xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>>>    xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
>>>    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
>>> https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
>>>    <jpa:enable />
>>>    <tx:enable />
>>>    <bean id="userService" class="org.data.impl.UserServiceImpl" />
>>>    <service ref="userService" interface="org.data.UserService" />
>>>    </blueprint>
>>> For testing I throw exception in my DAO:
>>> @Transactional(REQUIRED)
>>> public void addUser(User user) {
>>> em.persist(user);
>>> em.flush();
>>> throw new RuntimeException("On Purpose");
>>> }
>>> I expect the record not to be in the table due to rollback of the
>>> transaction, but it still shows up in my database table.
>>> Best regards,
>>> Alex soto
>
Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Tim Ward-2
Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

> On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:
>
> Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.
>
> Regards
> JB
>
>> On 16/05/2018 21:08, Alex Soto wrote:
>> Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
>> Best regards,
>> Alex soto
>>> On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <mailto:[hidden email]>> wrote:
>>>
>>> Same behavior with RequiresNew ?
>>>
>>> Regards
>>> JB
>>>
>>>> On 16/05/2018 19:44, Alex Soto wrote:
>>>> With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
>>>> I deployed these features (from Karaf’s enterprise  repository):
>>>> <feature>aries-blueprint</feature>
>>>> <feature>transaction</feature>
>>>> <feature>jndi</feature>
>>>> <feature>jdbc</feature>
>>>> <feature>jpa</feature>
>>>> <feature>pax-jdbc-mariadb</feature>
>>>>         <feature>pax-jdbc-config</feature>
>>>> <feature>pax-jdbc-pool-dbcp2</feature>
>>>> <feature>hibernate</feature>
>>>> My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
>>>>    osgi.jdbc.driver.name = mariadb
>>>>    dataSourceName=responder
>>>>    url
>>>>    = jdbc:mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
>>>>    user=XXXX
>>>>    password=XXXX
>>>>    databaseName=responder
>>>>    #Pool Config
>>>>    pool=dbcp2
>>>>    xa=true
>>>> My persistence.xml:
>>>>    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
>>>>         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>         xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>>>> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
>>>>             <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
>>>>                 <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>>>>             <!-- Only used when transaction-type=JTA -->
>>>>                 <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
>>>>             <!-- Only used when transaction-type=RESOURCE_LOCAL -->
>>>>                 <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
>>>>             <properties>
>>>>                     <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
>>>>                 <property name="hibernate.show_sql" value="true" />
>>>>                 <property name="hibernate.format_sql" value="true" />
>>>>                 <property name="hibernate.hbm2ddl.auto" value="none"/>
>>>>             </properties>
>>>>         </persistence-unit>
>>>>    </persistence>
>>>> My blueprint.xml:
>>>>    <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>>>>    xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>>>>    xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
>>>>    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>    xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
>>>> https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
>>>>    <jpa:enable />
>>>>    <tx:enable />
>>>>    <bean id="userService" class="org.data.impl.UserServiceImpl" />
>>>>    <service ref="userService" interface="org.data.UserService" />
>>>>    </blueprint>
>>>> For testing I throw exception in my DAO:
>>>> @Transactional(REQUIRED)
>>>> public void addUser(User user) {
>>>> em.persist(user);
>>>> em.flush();
>>>> throw new RuntimeException("On Purpose");
>>>> }
>>>> I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
>>>> Best regards,
>>>> Alex soto
Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
In reply to this post by jbonofre
I am calling flush on purpose, to be able to test, to force the data to be written to the database (not committed).
Anyway, I changed my method to this:


@Transactional(REQUIRES_NEW)
public void addUser(User user) {
List users = em.createQuery("Select u From User u").getResultList();
log.info("user count " + users.size());
em.persist(user);
users = em.createQuery("Select u From User u").getResultList();
log.info("user count " + users.size());
throw new RuntimeException("On Purpose");
}

Now I am not calling flush, but JPA will call it internally before running the second select.
Still the problem persists, i.e. the record is created, transaction is not rolled back.

From the logs:


2018-05-16T15:41:10,232 | INFO  | RMI TCP Connection(3)-127.0.0.1 | arjuna                           | 6 - org.ops4j.pax.logging.pax-logging-api - 1.10.1 | ARJUNA012170: TransactionStatusManager started on port 54960 and host 127.0.0.1 with service com.arjuna.ats.arjuna.recovery.ActionStatusService
2018-05-16T15:41:10,238 | DEBUG | RMI TCP Connection(3)-127.0.0.1 | JpaInterceptor                   | 48 - org.apache.aries.jpa.blueprint - 2.6.1 | PreCall for bean userService, method addUser
2018-05-16T15:41:10,239 | DEBUG | RMI TCP Connection(3)-127.0.0.1 | EMSupplierImpl                   | 50 - org.apache.aries.jpa.support - 2.6.1 | Creating EntityManager for persistence unit responderPersistenUnit, coordination txInterceptor.org.data.UserService.addUser
2018-05-16T15:41:10,246 | INFO  | RMI TCP Connection(3)-127.0.0.1 | UserServiceImpl                  | 135 - org.data - 1.0.0.SNAPSHOT | user count 0
2018-05-16T15:41:10,290 | INFO  | RMI TCP Connection(3)-127.0.0.1 | UserServiceImpl                  | 135 - org.data - 1.0.0.SNAPSHOT | user count 1
2018-05-16T15:41:10,291 | DEBUG | RMI TCP Connection(3)-127.0.0.1 | JpaInterceptor                   | 48 - org.apache.aries.jpa.blueprint - 2.6.1 | PostCallWithException for bean userService, method addUser
2018-05-16T15:41:10,307 | DEBUG | RMI TCP Connection(3)-127.0.0.1 | EMSupplierImpl                   | 50 - org.apache.aries.jpa.support - 2.6.1 | Coordination failed txInterceptor.org.data.UserService.addUser
2018-05-16T15:41:10,318 | DEBUG | RMI TCP Connection(3)-127.0.0.1 | TxInterceptorImpl                | 53 - org.apache.aries.transaction.blueprint - 2.1.0 | Setting transaction to rollback only because of exception 



Best regards,
Alex soto




On May 16, 2018, at 3:34 PM, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
        <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
   osgi.jdbc.driver.name = mariadb
   dataSourceName=responder
   url
   = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
   user=XXXX
   password=XXXX
   databaseName=responder
   #Pool Config
   pool=dbcp2
   xa=true
My persistence.xml:
   <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
            <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
            <!-- Only used when transaction-type=JTA -->
                <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
            <!-- Only used when transaction-type=RESOURCE_LOCAL -->
                <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
            <properties>
                    <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
                <property name="hibernate.hbm2ddl.auto" value="none"/>
            </properties>
        </persistence-unit>
   </persistence>
My blueprint.xml:
   <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
   xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
   <jpa:enable />
   <tx:enable />
   <bean id="userService" class="org.data.impl.UserServiceImpl" />
   <service ref="userService" interface="org.data.UserService" />
   </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto

Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
In reply to this post by Tim Ward-2
Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto

Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Tim Ward-2
The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto

Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto


Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

jbonofre
Hi Alex,

I fully agree, and we know it's an area where we have to improve.

That's why we started a fully set of examples that will be:

1. part of the Karaf distribution
2. used in the itests to verify the behavior is correct.

You can find the WIP  on the example here:

https://github.com/apache/karaf/pull/484

I'm still polishing/cleaning/adding examples but the idea is to provide a large
set of turnkey samples users can start with.

Please,  keep  me posted if you want to see additional examples for the first
inclusion.

Thanks !
Regards
JB

On 05/16/2018 10:25 PM, Alex Soto wrote:

> I agree, it s very frustrating and time consuming. Almost impossible to get it
> right.
> I may try the OSGi R7, but I am not sure of its adoption level at this time,
> availability of bundles, examples, support by Karaf, etc.
>
>
> Anyway, back to my current stack.  I only see one DataSource being registered:
>
> karaf@root()> service:list DataSource
> [javax.sql.DataSource]
> ----------------------
>  databaseName = responder
>  dataSourceName = responder
>  osgi.jdbc.driver.name = mariadb
>  osgi.jndi.service.name = responder
>  service.bundleid = 14
>  service.factoryPid = org.ops4j.datasource
>  service.id <http://service.id> = 194
>  service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
>  service.scope = singleton
>  url = jdbc:mariadb:XXXXXX
> Provided by : 
>  OPS4J Pax JDBC Config (14)
> Used by: 
>  Data (135)
>
>
> Not sure what to do with this.  
> I specified the following in the configuration:
>
> pool=narayana
> xa=true
>
> Best regards,
> Alex soto
>
>
>
>
>> On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> The structure of the JNDI name is defined by the JNDI service specification. 
>>
>> osgi:service/<interface name>[/<filter>]
>>
>> So in this case both of your services should be DataSource instances, but they
>> should have different filters. 
>>
>> The important thing is to make sure you have an JTA enlisting DataSource
>> registered as a service (this isn’t just your normal DataSource), then to
>> build a filter which selects that. One option for this is to use the
>> enlistment whiteboard from Aries (not well
>> documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc
>>
>> This is a non-trivial thing to do, which is why I keep mentioning Transaction
>> Control which handles the enlistment reliably without the layers of services. 
>>
>> Best Regards,
>>
>> Tim
>>
>> Sent from my iPhone
>>
>> On 16 May 2018, at 21:57, Alex Soto <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>> Thank you Tim.
>>>
>>> Any idea what the JNDI names would be?
>>> It is Pax-JDBC creating these JNDI names, so I have no idea.
>>>
>>> From the Karaf console:
>>>
>>>
>>> karaf@root()> jndi:names 
>>> JNDI Name              │ Class Name
>>> ───────────────────────┼───────────────────────────────────────────────
>>> osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
>>> osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl
>>>
>>>
>>> Best regards,
>>> Alex soto
>>>
>>>
>>>
>>>
>>>> On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]
>>>> <mailto:[hidden email]>> wrote:
>>>>
>>>> Just looking quickly.
>>>>
>>>> You have the same JNDI name for both JTA and non JTA DataSources. This is
>>>> clearly wrong as the DataSource cannot simultaneously be enlisted in the
>>>> Transaction and not enlisted. The comments also indicate a misunderstanding
>>>> of the purpose of the non-jta-datasource, which absolutely is used with JTA
>>>> EntityManagers (for things like sequence allocation and out of band
>>>> optimisations). You really do need to have both and they do need to behave
>>>> differently.
>>>>
>>>> At a guess your DataSource is not enlisted with the transaction manager
>>>> present in the system.  This usually happens by configuring a (otherwise
>>>> invisible) DataSource wrapper There is nothing forcing you to make this
>>>> happen (or checking that it does) hence your transactions would be broken.
>>>> This is one of the several reasons I try to direct people to Transaction
>>>> Control where the model actively pushes you toward transactions that
>>>> actually work, rather than hiding all the magic behind an annotation.
>>>>
>>>> Hopefully this gives you some clues as to what might be wrong.
>>>>
>>>> Best Regards,
>>>>
>>>> Tim
>>>>
>>>> Sent from my iPhone
>>>>
>>>>> On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]
>>>>> <mailto:[hidden email]>> wrote:
>>>>>
>>>>> Are you sure about your code ? Flush looks weird to me and it seems you
>>>>> don't use container managed transaction.
>>>>>
>>>>> Regards
>>>>> JB
>>>>>
>>>>>> On 16/05/2018 21:08, Alex Soto wrote:
>>>>>> Yes, same result.  I even tried with Narayana Transaction Manager, and
>>>>>> same result.
>>>>>> Best regards,
>>>>>> Alex soto
>>>>>>> On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email]
>>>>>>> <mailto:[hidden email]> <mailto:[hidden email]>> wrote:
>>>>>>>
>>>>>>> Same behavior with RequiresNew ?
>>>>>>>
>>>>>>> Regards
>>>>>>> JB
>>>>>>>
>>>>>>>> On 16/05/2018 19:44, Alex Soto wrote:
>>>>>>>> With Karaf version 4.2.0, Rollback is not working with MariaDB and
>>>>>>>> InnoDB tables.
>>>>>>>> I deployed these features (from Karaf’s enterprise  repository):
>>>>>>>> <feature>aries-blueprint</feature>
>>>>>>>> <feature>transaction</feature>
>>>>>>>> <feature>jndi</feature>
>>>>>>>> <feature>jdbc</feature>
>>>>>>>> <feature>jpa</feature>
>>>>>>>> <feature>pax-jdbc-mariadb</feature>
>>>>>>>>        <feature>pax-jdbc-config</feature>
>>>>>>>> <feature>pax-jdbc-pool-dbcp2</feature>
>>>>>>>> <feature>hibernate</feature>
>>>>>>>> My Data Source is configured in the file
>>>>>>>> /org.ops4j.datasource-responder.cfg/
>>>>>>>>   osgi.jdbc.driver.name = mariadb
>>>>>>>>   dataSourceName=responder
>>>>>>>>   url
>>>>>>>>   =
>>>>>>>> jdbc:mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
>>>>>>>>   user=XXXX
>>>>>>>>   password=XXXX
>>>>>>>>   databaseName=responder
>>>>>>>>   #Pool Config
>>>>>>>>   pool=dbcp2
>>>>>>>>   xa=true
>>>>>>>> My persistence.xml:
>>>>>>>>   <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
>>>>>>>>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>>>>        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>>>>>>>> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
>>>>>>>>            <persistence-unit name="responderPersistenUnit"
>>>>>>>> transaction-type="JTA">
>>>>>>>>                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>>>>>>>>            <!-- Only used when transaction-type=JTA -->
>>>>>>>>                <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
>>>>>>>>            <!-- Only used when transaction-type=RESOURCE_LOCAL -->
>>>>>>>>                <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
>>>>>>>>            <properties>
>>>>>>>>                    <property name=“hibernate.dialect"
>>>>>>>> value="org.hibernate.dialect.MySQL5Dialect" />
>>>>>>>>                <property name="hibernate.show_sql" value="true" />
>>>>>>>>                <property name="hibernate.format_sql" value="true" />
>>>>>>>>                <property name="hibernate.hbm2ddl.auto" value="none"/>
>>>>>>>>            </properties>
>>>>>>>>        </persistence-unit>
>>>>>>>>   </persistence>
>>>>>>>> My blueprint.xml:
>>>>>>>>   <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>>>>>>>>   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>>>>>>>>   xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
>>>>>>>>   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>>>>   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
>>>>>>>> https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
>>>>>>>>   <jpa:enable />
>>>>>>>>   <tx:enable />
>>>>>>>>   <bean id="userService" class="org.data.impl.UserServiceImpl" />
>>>>>>>>   <service ref="userService" interface="org.data.UserService" />
>>>>>>>>   </blueprint>
>>>>>>>> For testing I throw exception in my DAO:
>>>>>>>> @Transactional(REQUIRED)
>>>>>>>> public void addUser(User user) {
>>>>>>>> em.persist(user);
>>>>>>>> em.flush();
>>>>>>>> throw new RuntimeException("On Purpose");
>>>>>>>> }
>>>>>>>> I expect the record not to be in the table due to rollback of the
>>>>>>>> transaction, but it still shows up in my database table.
>>>>>>>> Best regards,
>>>>>>>> Alex soto
>>>
>

--
Jean-Baptiste Onofré
[hidden email]
http://blog.nanthrax.net
Talend - http://www.talend.com
Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

jbonofre
In reply to this post by Alex Soto
Hi Alex,

I fully agree, and we know it's an area where we have to improve.

That's why we started a fully set of examples that will be:

1. part of the Karaf distribution
2. used in the itests to verify the behavior is correct.

You can find the WIP  on the example here:

https://github.com/apache/karaf/pull/484

I'm still polishing/cleaning/adding examples but the idea is to provide a large
set of turnkey samples users can start with.

Please,  keep  me posted if you want to see additional examples for the first
inclusion.

Thanks !
Regards
JB

On 05/16/2018 10:25 PM, Alex Soto wrote:

> I agree, it s very frustrating and time consuming. Almost impossible to get it
> right.
> I may try the OSGi R7, but I am not sure of its adoption level at this time,
> availability of bundles, examples, support by Karaf, etc.
>
>
> Anyway, back to my current stack.  I only see one DataSource being registered:
>
> karaf@root()> service:list DataSource
> [javax.sql.DataSource]
> ----------------------
>  databaseName = responder
>  dataSourceName = responder
>  osgi.jdbc.driver.name = mariadb
>  osgi.jndi.service.name = responder
>  service.bundleid = 14
>  service.factoryPid = org.ops4j.datasource
>  service.id <http://service.id> = 194
>  service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
>  service.scope = singleton
>  url = jdbc:mariadb:XXXXXX
> Provided by : 
>  OPS4J Pax JDBC Config (14)
> Used by: 
>  Data (135)
>
>
> Not sure what to do with this.  
> I specified the following in the configuration:
>
> pool=narayana
> xa=true
>
> Best regards,
> Alex soto
>
>
>
>
>> On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> The structure of the JNDI name is defined by the JNDI service specification. 
>>
>> osgi:service/<interface name>[/<filter>]
>>
>> So in this case both of your services should be DataSource instances, but they
>> should have different filters. 
>>
>> The important thing is to make sure you have an JTA enlisting DataSource
>> registered as a service (this isn’t just your normal DataSource), then to
>> build a filter which selects that. One option for this is to use the
>> enlistment whiteboard from Aries (not well
>> documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc
>>
>> This is a non-trivial thing to do, which is why I keep mentioning Transaction
>> Control which handles the enlistment reliably without the layers of services. 
>>
>> Best Regards,
>>
>> Tim
>>
>> Sent from my iPhone
>>
>> On 16 May 2018, at 21:57, Alex Soto <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>> Thank you Tim.
>>>
>>> Any idea what the JNDI names would be?
>>> It is Pax-JDBC creating these JNDI names, so I have no idea.
>>>
>>> From the Karaf console:
>>>
>>>
>>> karaf@root()> jndi:names 
>>> JNDI Name              │ Class Name
>>> ───────────────────────┼───────────────────────────────────────────────
>>> osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
>>> osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl
>>>
>>>
>>> Best regards,
>>> Alex soto
>>>
>>>
>>>
>>>
>>>> On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]
>>>> <mailto:[hidden email]>> wrote:
>>>>
>>>> Just looking quickly.
>>>>
>>>> You have the same JNDI name for both JTA and non JTA DataSources. This is
>>>> clearly wrong as the DataSource cannot simultaneously be enlisted in the
>>>> Transaction and not enlisted. The comments also indicate a misunderstanding
>>>> of the purpose of the non-jta-datasource, which absolutely is used with JTA
>>>> EntityManagers (for things like sequence allocation and out of band
>>>> optimisations). You really do need to have both and they do need to behave
>>>> differently.
>>>>
>>>> At a guess your DataSource is not enlisted with the transaction manager
>>>> present in the system.  This usually happens by configuring a (otherwise
>>>> invisible) DataSource wrapper There is nothing forcing you to make this
>>>> happen (or checking that it does) hence your transactions would be broken.
>>>> This is one of the several reasons I try to direct people to Transaction
>>>> Control where the model actively pushes you toward transactions that
>>>> actually work, rather than hiding all the magic behind an annotation.
>>>>
>>>> Hopefully this gives you some clues as to what might be wrong.
>>>>
>>>> Best Regards,
>>>>
>>>> Tim
>>>>
>>>> Sent from my iPhone
>>>>
>>>>> On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]
>>>>> <mailto:[hidden email]>> wrote:
>>>>>
>>>>> Are you sure about your code ? Flush looks weird to me and it seems you
>>>>> don't use container managed transaction.
>>>>>
>>>>> Regards
>>>>> JB
>>>>>
>>>>>> On 16/05/2018 21:08, Alex Soto wrote:
>>>>>> Yes, same result.  I even tried with Narayana Transaction Manager, and
>>>>>> same result.
>>>>>> Best regards,
>>>>>> Alex soto
>>>>>>> On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email]
>>>>>>> <mailto:[hidden email]> <mailto:[hidden email]>> wrote:
>>>>>>>
>>>>>>> Same behavior with RequiresNew ?
>>>>>>>
>>>>>>> Regards
>>>>>>> JB
>>>>>>>
>>>>>>>> On 16/05/2018 19:44, Alex Soto wrote:
>>>>>>>> With Karaf version 4.2.0, Rollback is not working with MariaDB and
>>>>>>>> InnoDB tables.
>>>>>>>> I deployed these features (from Karaf’s enterprise  repository):
>>>>>>>> <feature>aries-blueprint</feature>
>>>>>>>> <feature>transaction</feature>
>>>>>>>> <feature>jndi</feature>
>>>>>>>> <feature>jdbc</feature>
>>>>>>>> <feature>jpa</feature>
>>>>>>>> <feature>pax-jdbc-mariadb</feature>
>>>>>>>>        <feature>pax-jdbc-config</feature>
>>>>>>>> <feature>pax-jdbc-pool-dbcp2</feature>
>>>>>>>> <feature>hibernate</feature>
>>>>>>>> My Data Source is configured in the file
>>>>>>>> /org.ops4j.datasource-responder.cfg/
>>>>>>>>   osgi.jdbc.driver.name = mariadb
>>>>>>>>   dataSourceName=responder
>>>>>>>>   url
>>>>>>>>   =
>>>>>>>> jdbc:mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
>>>>>>>>   user=XXXX
>>>>>>>>   password=XXXX
>>>>>>>>   databaseName=responder
>>>>>>>>   #Pool Config
>>>>>>>>   pool=dbcp2
>>>>>>>>   xa=true
>>>>>>>> My persistence.xml:
>>>>>>>>   <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
>>>>>>>>        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>>>>        xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
>>>>>>>> http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
>>>>>>>>            <persistence-unit name="responderPersistenUnit"
>>>>>>>> transaction-type="JTA">
>>>>>>>>                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
>>>>>>>>            <!-- Only used when transaction-type=JTA -->
>>>>>>>>                <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
>>>>>>>>            <!-- Only used when transaction-type=RESOURCE_LOCAL -->
>>>>>>>>                <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
>>>>>>>>            <properties>
>>>>>>>>                    <property name=“hibernate.dialect"
>>>>>>>> value="org.hibernate.dialect.MySQL5Dialect" />
>>>>>>>>                <property name="hibernate.show_sql" value="true" />
>>>>>>>>                <property name="hibernate.format_sql" value="true" />
>>>>>>>>                <property name="hibernate.hbm2ddl.auto" value="none"/>
>>>>>>>>            </properties>
>>>>>>>>        </persistence-unit>
>>>>>>>>   </persistence>
>>>>>>>> My blueprint.xml:
>>>>>>>>   <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
>>>>>>>>   xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
>>>>>>>>   xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
>>>>>>>>   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>>>>>>   xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
>>>>>>>> https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
>>>>>>>>   <jpa:enable />
>>>>>>>>   <tx:enable />
>>>>>>>>   <bean id="userService" class="org.data.impl.UserServiceImpl" />
>>>>>>>>   <service ref="userService" interface="org.data.UserService" />
>>>>>>>>   </blueprint>
>>>>>>>> For testing I throw exception in my DAO:
>>>>>>>> @Transactional(REQUIRED)
>>>>>>>> public void addUser(User user) {
>>>>>>>> em.persist(user);
>>>>>>>> em.flush();
>>>>>>>> throw new RuntimeException("On Purpose");
>>>>>>>> }
>>>>>>>> I expect the record not to be in the table due to rollback of the
>>>>>>>> transaction, but it still shows up in my database table.
>>>>>>>> Best regards,
>>>>>>>> Alex soto
>>>
>

--
Jean-Baptiste Onofré
[hidden email]
http://blog.nanthrax.net
Talend - http://www.talend.com
Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Tim Ward-2
In reply to this post by Alex Soto
The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto


Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto



Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Tim Ward-2
It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto



Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
Allright,  I am trying to follow the EnRoute tutorial.

I am getting this error:

[ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/) -> [Help 1]


Any idea (time frame) when this will move from SNAPSHOT dependencies?


Best regards,
Alex soto




On May 17, 2018, at 11:08 AM, Tim Ward <[hidden email]> wrote:

It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto




Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
In reply to this post by Tim Ward-2
Allright,  I am trying to follow the EnRoute tutorial.

I am getting this error:

[ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/) -> [Help 1]


Any idea (time frame) when this will move from SNAPSHOT dependencies?


Best regards,
Alex soto




On May 17, 2018, at 11:08 AM, Tim Ward <[hidden email]> wrote:

It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto




Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Tim Ward-2
In reply to this post by Alex Soto
Hi Alex,

Bnd 4.0.0 was only released last Sunday, but this should have been changed yesterday in this commit https://github.com/osgi/osgi.enroute/commit/9f9857c3d317cd08a7aaf7327c1904676299f9ee to make sure enRoute kept building. 

EnRoute is automatically pushed to the sonatype OSGi nexus repository, so is it possible that you’re running offline, or firewalled from the repo? You should be able to force snapshot updates from the Maven command line. 

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 18:26, Alex Soto <[hidden email]> wrote:

Allright,  I am trying to follow the EnRoute tutorial.

I am getting this error:

[ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/) -> [Help 1]


Any idea (time frame) when this will move from SNAPSHOT dependencies?


Best regards,
Alex soto




On May 17, 2018, at 11:08 AM, Tim Ward <[hidden email]> wrote:

It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto




Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
Thanks Tim, 

I was using branch R7, changed to master, it builds now.

Now I have updated my project to OSGi 7 with Transaction Control, how do I deploy to Karaf?
i.e., what bundles/features do I need?


Best regards,
Alex soto




On May 17, 2018, at 2:08 PM, Tim Ward <[hidden email]> wrote:

Hi Alex,

Bnd 4.0.0 was only released last Sunday, but this should have been changed yesterday in this commit https://github.com/osgi/osgi.enroute/commit/9f9857c3d317cd08a7aaf7327c1904676299f9ee to make sure enRoute kept building. 

EnRoute is automatically pushed to the sonatype OSGi nexus repository, so is it possible that you’re running offline, or firewalled from the repo? You should be able to force snapshot updates from the Maven command line. 

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 18:26, Alex Soto <[hidden email]> wrote:

Allright,  I am trying to follow the EnRoute tutorial.

I am getting this error:

[ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/) -> [Help 1]


Any idea (time frame) when this will move from SNAPSHOT dependencies?


Best regards,
Alex soto




On May 17, 2018, at 11:08 AM, Tim Ward <[hidden email]> wrote:

It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto





Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Tim Ward-2
Hi Alex,

The bundles you need are listed in the bndrun for the JPA version of the enRoute application, but as I think you’re using OpenJPA (rather than Hibernate) it may help to explain things in relation to the Transaction Control JPA integration test for OpenJPA. I’m sure that at least some of this will be stuff you already know, but I’m trying to make sure I give a compete explanation. 

This method defines some extra properties to add to the persistence unit. It references a couple of open bugs in OpenJPA which may or may not affect you. It also adds schema generation as OpenJPA does not support the standard properties from JPA 2.1 https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleOpenJPA_2_4_1_Test.java#L34

This method defines the OpenJPA bundles and their immediate dependencies. https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleOpenJPA_2_4_1_Test.java#L48

You then need:

• Aries JPA 2.7.0 - this provides the OSGi JPA Service 1.1 RI (1.1 features are needed by the Aries Tx Control JPA resource provider to support XA)


• Aries Tx Control JPA resource provider - either XA or local depending on your needs. Note that you can’t use the XA provider with the local service, but you can use the local provider with the XA service (although this doesn’t make a lot of sense to do). For example https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L377

• A JDBC Service implementation supporting your database driver. H2 supports this natively (which is why it is used in many examples) but MariaDB does not. Therefore you will need to deploy PAX-JDBC’s support. See https://github.com/ops4j/org.ops4j.pax.jdbc/tree/master/pax-jdbc-mariadb

You then have the option of either programmatically assembling your Resource Provider, or using configuration. Configuration is generally easier and is what I normally recommend. At that point you need to create a factory configuration for the relevant PID (it depends on whether you use the local or XA resource provider, see https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L175)

The necessary configuration properties are:

• url - the JDBC URL for your database 
• osgi.jdbc.driver.class - the database driver class name, in your case org.mariadb.jdbc.Driver
• osgi.unit.name - the name of your persistence unit 

The result of this configuration will be a JPAEntityManagerProvider service registered in the service registry (using your EntityManagerFactoryBuilder and the MariaDB DataSourceFactory). You can then Inject that service into your code and combine it with the TransactionControl service to make a thread safe EntityManager that you can use in all your requests (just like the enRoute example does). 

I hope this helps,

Tim

Sent from my iPhone

On 17 May 2018, at 22:46, Alex Soto <[hidden email]> wrote:

Thanks Tim, 

I was using branch R7, changed to master, it builds now.

Now I have updated my project to OSGi 7 with Transaction Control, how do I deploy to Karaf?
i.e., what bundles/features do I need?


Best regards,
Alex soto




On May 17, 2018, at 2:08 PM, Tim Ward <[hidden email]> wrote:

Hi Alex,

Bnd 4.0.0 was only released last Sunday, but this should have been changed yesterday in this commit https://github.com/osgi/osgi.enroute/commit/9f9857c3d317cd08a7aaf7327c1904676299f9ee to make sure enRoute kept building. 

EnRoute is automatically pushed to the sonatype OSGi nexus repository, so is it possible that you’re running offline, or firewalled from the repo? You should be able to force snapshot updates from the Maven command line. 

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 18:26, Alex Soto <[hidden email]> wrote:

Allright,  I am trying to follow the EnRoute tutorial.

I am getting this error:

[ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/) -> [Help 1]


Any idea (time frame) when this will move from SNAPSHOT dependencies?


Best regards,
Alex soto




On May 17, 2018, at 11:08 AM, Tim Ward <[hidden email]> wrote:

It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto





Reply | Threaded
Open this post in threaded view
|

Re: MariaDB/JPA Transaction rollback not working

Alex Soto
Thank you Tim for the very detailed explanation.
There are  two problems I don’t know how to resolve:

1- BND generates this for my bundle: 

Require-Capability:  osgi.extender;filter:="(&(osgi.extender=osgi.component)(version>=1.3.0)(!(version>=2.0.0)))”

This is because I use the @Component and @Reference annotations.  This is strange, since I should be using OSGi R7, so I am not sure why it is saying 1.3.0.  Now when try to run in Karaf, even though I am installing scr feature, it fails with unresolved requirement.

Since I could not find OSGi R7 in public Maven Repos, I followed EnRoute depending on:
      <dependency>
        <groupId>org.osgi.enroute</groupId>
        <artifactId>osgi-api</artifactId>
        <version>7.0.0-SNAPSHOT</version>
        <type>pom</type>
        <scope>provided</scope>
      </dependency>
      <dependency>
        <groupId>org.osgi.enroute</groupId>
        <artifactId>enterprise-api</artifactId>
        <version>7.0.0-SNAPSHOT</version>
        <type>pom</type>
        <scope>provided</scope>
      </dependency>

2- This is minor, and I see it also in the EnRoute project. While the Maven build succeeds, Eclipse BND plugin shows 2 errors:

The default package '.' is not permitted by the Import-Package syntax. This can be caused by compile errors in Eclipse because Eclipse creates valid class files regardless of compile errors. The following package(s) import from the default package [org.enquery.encryptedquery.responder.data.service.impl] (biz.aQute.bnd:bnd-maven-plugin:4.0.0:bnd-process:default:process-classes) pom.xml /encryptedquery-responder-data line 0 Maven Build Participant Problem 

The project was not built since its build path is incomplete. Cannot find the class file for javax.persistence.EntityManager. Fix the build path then try building this project encryptedquery-responder-data Unknown Java Problem

 


Best regards,
Alex soto




On May 18, 2018, at 5:23 AM, Tim Ward <[hidden email]> wrote:

Hi Alex,

The bundles you need are listed in the bndrun for the JPA version of the enRoute application, but as I think you’re using OpenJPA (rather than Hibernate) it may help to explain things in relation to the Transaction Control JPA integration test for OpenJPA. I’m sure that at least some of this will be stuff you already know, but I’m trying to make sure I give a compete explanation. 

This method defines some extra properties to add to the persistence unit. It references a couple of open bugs in OpenJPA which may or may not affect you. It also adds schema generation as OpenJPA does not support the standard properties from JPA 2.1 https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleOpenJPA_2_4_1_Test.java#L34

This method defines the OpenJPA bundles and their immediate dependencies. https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/SimpleOpenJPA_2_4_1_Test.java#L48

You then need:

• Aries JPA 2.7.0 - this provides the OSGi JPA Service 1.1 RI (1.1 features are needed by the Aries Tx Control JPA resource provider to support XA)


• Aries Tx Control JPA resource provider - either XA or local depending on your needs. Note that you can’t use the XA provider with the local service, but you can use the local provider with the XA service (although this doesn’t make a lot of sense to do). For example https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L377

• A JDBC Service implementation supporting your database driver. H2 supports this natively (which is why it is used in many examples) but MariaDB does not. Therefore you will need to deploy PAX-JDBC’s support. See https://github.com/ops4j/org.ops4j.pax.jdbc/tree/master/pax-jdbc-mariadb

You then have the option of either programmatically assembling your Resource Provider, or using configuration. Configuration is generally easier and is what I normally recommend. At that point you need to create a factory configuration for the relevant PID (it depends on whether you use the local or XA resource provider, see https://github.com/apache/aries-tx-control/blob/master/tx-control-providers/jpa/tx-control-jpa-itests/src/test/java/org/apache/aries/tx/control/itests/AbstractJPATransactionTest.java#L175)

The necessary configuration properties are:

• url - the JDBC URL for your database 
• osgi.jdbc.driver.class - the database driver class name, in your case org.mariadb.jdbc.Driver
• osgi.unit.name - the name of your persistence unit 

The result of this configuration will be a JPAEntityManagerProvider service registered in the service registry (using your EntityManagerFactoryBuilder and the MariaDB DataSourceFactory). You can then Inject that service into your code and combine it with the TransactionControl service to make a thread safe EntityManager that you can use in all your requests (just like the enRoute example does). 

I hope this helps,

Tim

Sent from my iPhone

On 17 May 2018, at 22:46, Alex Soto <[hidden email]> wrote:

Thanks Tim, 

I was using branch R7, changed to master, it builds now.

Now I have updated my project to OSGi 7 with Transaction Control, how do I deploy to Karaf?
i.e., what bundles/features do I need?


Best regards,
Alex soto




On May 17, 2018, at 2:08 PM, Tim Ward <[hidden email]> wrote:

Hi Alex,

Bnd 4.0.0 was only released last Sunday, but this should have been changed yesterday in this commit https://github.com/osgi/osgi.enroute/commit/9f9857c3d317cd08a7aaf7327c1904676299f9ee to make sure enRoute kept building. 

EnRoute is automatically pushed to the sonatype OSGi nexus repository, so is it possible that you’re running offline, or firewalled from the repo? You should be able to force snapshot updates from the Maven command line. 

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 18:26, Alex Soto <[hidden email]> wrote:

Allright,  I am trying to follow the EnRoute tutorial.

I am getting this error:

[ERROR] Plugin biz.aQute.bnd:bnd-maven-plugin:4.0.0-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact biz.aQute.bnd:bnd-maven-plugin:jar:4.0.0-SNAPSHOT in Bnd Snapshots (https://bndtools.ci.cloudbees.com/job/bnd.master/lastSuccessfulBuild/artifact/dist/bundles/) -> [Help 1]


Any idea (time frame) when this will move from SNAPSHOT dependencies?


Best regards,
Alex soto




On May 17, 2018, at 11:08 AM, Tim Ward <[hidden email]> wrote:

It is highly unlikely that you’ll hit the same issues. The transaction control resource provider uses the DataSourceFactory directly to create a DataSource (either progamatically using a factory service or via config admin) that enlists itself in the ongoing transaction. This means that the answer to your question is “with Transaction Control you don’t have to do that because it does it automatically”

If you want to use XA transactions then the only requirement is that the DataSourceFactory can produce an XADataSource, otherwise it just uses the standard JDBC API to commit/rollback. If your DataSourceFactory doesn’t support XA then use the local resource provider implementation.

Best Regards,

Tim

Sent from my iPhone

On 17 May 2018, at 15:17, Alex Soto <[hidden email]> wrote:

I will take a look at these examples.

However, I think that if I cannot get a MariaDB DataSource that supports transactions, then it will still not work, right?
If the examples use H2 database, I still may get different results when I change to MariaDB, and I will find myself in the same spot as of now.

So, the question remains about what is the correct way how to register a transaction aware MariaDB DataSource.


Best regards,
Alex soto




On May 17, 2018, at 1:46 AM, Tim Ward <[hidden email]> wrote:

The best place to start when looking for OSGi R7 examples is the enRoute Project. It contains Maven Archetypes, examples and worked tutorials for building applications using R7 specifications. 


Most of the projects in use are just new versions of long established OSGi implementations from Aries and Felix. The majority of them are already released and in Maven Central. Those that are still in the process of releasing (pretty much just the JAX-RS whiteboard) are available in the Apache Snapshots repository. I am not aware of any implementations that require R7 framework features, so all of them should run on Karaf.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 22:25, Alex Soto <[hidden email]> wrote:

I agree, it s very frustrating and time consuming. Almost impossible to get it right.
I may try the OSGi R7, but I am not sure of its adoption level at this time, availability of bundles, examples, support by Karaf, etc.


Anyway, back to my current stack.  I only see one DataSource being registered:

karaf@root()> service:list DataSource
[javax.sql.DataSource]
----------------------
 databaseName = responder
 dataSourceName = responder
 osgi.jdbc.driver.name = mariadb
 osgi.jndi.service.name = responder
 service.bundleid = 14
 service.factoryPid = org.ops4j.datasource
 service.id = 194
 service.pid = org.ops4j.datasource.feb33f6d-dc46-4bc7-a417-ad6bdd5a6ee5
 service.scope = singleton
 url = jdbc:mariadb:XXXXXX
Provided by : 
 OPS4J Pax JDBC Config (14)
Used by: 
 Data (135)


Not sure what to do with this.  
I specified the following in the configuration:

pool=narayana
xa=true

Best regards,
Alex soto




On May 16, 2018, at 4:12 PM, Tim Ward <[hidden email]> wrote:

The structure of the JNDI name is defined by the JNDI service specification. 

osgi:service/<interface name>[/<filter>]

So in this case both of your services should be DataSource instances, but they should have different filters. 

The important thing is to make sure you have an JTA enlisting DataSource registered as a service (this isn’t just your normal DataSource), then to build a filter which selects that. One option for this is to use the enlistment whiteboard from Aries (not well documented) https://github.com/apache/aries/tree/trunk/transaction/transaction-jdbc

This is a non-trivial thing to do, which is why I keep mentioning Transaction Control which handles the enlistment reliably without the layers of services. 

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:57, Alex Soto <[hidden email]> wrote:

Thank you Tim.

Any idea what the JNDI names would be?
It is Pax-JDBC creating these JNDI names, so I have no idea.

From the Karaf console:


karaf@root()> jndi:names 
JNDI Name              │ Class Name
───────────────────────┼───────────────────────────────────────────────
osgi:service/responder │ org.mariadb.jdbc.MySQLDataSource
osgi:service/jndi      │ org.apache.karaf.jndi.internal.JndiServiceImpl


Best regards,
Alex soto




On May 16, 2018, at 3:48 PM, Tim Ward <[hidden email]> wrote:

Just looking quickly.

You have the same JNDI name for both JTA and non JTA DataSources. This is clearly wrong as the DataSource cannot simultaneously be enlisted in the Transaction and not enlisted. The comments also indicate a misunderstanding of the purpose of the non-jta-datasource, which absolutely is used with JTA EntityManagers (for things like sequence allocation and out of band optimisations). You really do need to have both and they do need to behave differently.

At a guess your DataSource is not enlisted with the transaction manager present in the system.  This usually happens by configuring a (otherwise invisible) DataSource wrapper There is nothing forcing you to make this happen (or checking that it does) hence your transactions would be broken. This is one of the several reasons I try to direct people to Transaction Control where the model actively pushes you toward transactions that actually work, rather than hiding all the magic behind an annotation.

Hopefully this gives you some clues as to what might be wrong.

Best Regards,

Tim

Sent from my iPhone

On 16 May 2018, at 21:34, Jean-Baptiste Onofré <[hidden email]> wrote:

Are you sure about your code ? Flush looks weird to me and it seems you don't use container managed transaction.

Regards
JB

On 16/05/2018 21:08, Alex Soto wrote:
Yes, same result.  I even tried with Narayana Transaction Manager, and same result.
Best regards,
Alex soto
On May 16, 2018, at 2:56 PM, Jean-Baptiste Onofré <[hidden email] <[hidden email]>> wrote:

Same behavior with RequiresNew ?

Regards
JB

On 16/05/2018 19:44, Alex Soto wrote:
With Karaf version 4.2.0, Rollback is not working with MariaDB and InnoDB tables.
I deployed these features (from Karaf’s enterprise  repository):
<feature>aries-blueprint</feature>
<feature>transaction</feature>
<feature>jndi</feature>
<feature>jdbc</feature>
<feature>jpa</feature>
<feature>pax-jdbc-mariadb</feature>
       <feature>pax-jdbc-config</feature>
<feature>pax-jdbc-pool-dbcp2</feature>
<feature>hibernate</feature>
My Data Source is configured in the file /org.ops4j.datasource-responder.cfg/
  osgi.jdbc.driver.name = mariadb
  dataSourceName=responder
  url
  = jdbc:<a href="mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&amp;useServerPrepStmts=true&amp;autocommit=false" class="">mariadb://mariadb.local:3306/responder?characterEncoding=UTF-8&useServerPrepStmts=true&autocommit=false
  user=XXXX
  password=XXXX
  databaseName=responder
  #Pool Config
  pool=dbcp2
  xa=true
My persistence.xml:
  <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
           <persistence-unit name="responderPersistenUnit" transaction-type="JTA">
               <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
           <!-- Only used when transaction-type=JTA -->
               <jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</jta-data-source>
           <!-- Only used when transaction-type=RESOURCE_LOCAL -->
               <non-jta-data-source>osgi:service/javax.sql.DataSource/(osgi.jndi.service.name=responder)</non-jta-data-source>
           <properties>
                   <property name=“hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
               <property name="hibernate.show_sql" value="true" />
               <property name="hibernate.format_sql" value="true" />
               <property name="hibernate.hbm2ddl.auto" value="none"/>
           </properties>
       </persistence-unit>
  </persistence>
My blueprint.xml:
  <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
  xmlns:jpa="http://aries.apache.org/xmlns/jpa/v2.0.0"
  xmlns:tx="http://aries.apache.org/xmlns/transactions/v2.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
https://osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
  <jpa:enable />
  <tx:enable />
  <bean id="userService" class="org.data.impl.UserServiceImpl" />
  <service ref="userService" interface="org.data.UserService" />
  </blueprint>
For testing I throw exception in my DAO:
@Transactional(REQUIRED)
public void addUser(User user) {
em.persist(user);
em.flush();
throw new RuntimeException("On Purpose");
}
I expect the record not to be in the table due to rollback of the transaction, but it still shows up in my database table.
Best regards,
Alex soto






12