Question

I have the following:

An JAR module, containing a DAO class like so:

public class WhateverDao {

    @PersistenceContext(name="pu")
    EntityManager entityManager;

public Whatever saveOrUpdate(Whatever entity) {
    //entityManager.joinTransaction();
    return entityManager.merge(entity);
}

The jar also contains a persistence.xml like so:

<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"
    version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
    <persistence-unit name="pu" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc/jee6Test_mysql_datasource</jta-data-source>
        <!-- Entities classes declared here -->
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
        </properties>       
    </persistence-unit>
</persistence>

and an empty beans.xml file.

This jar is used inside a web application (a WAR file), where the DAO is injected into a stateless EJB like so:

@Stateless
@LocalBean
public class WhateverEJBImpl {

    @Inject
    private WhateverDao whateverDao;

    public void saveWhatever(Whatever whatever) throws IOException {
        whateverDao.saveOrUpdate(whatever); 
    }

My issue basicaly is that I can't manage to make this code actually persist something in the database. As far as I understand:

  • my EntityManager should be "Container Managed" (due to how I configured it in the persistence.xml, and the fact that I obtain it via @PersistenceContext annotation, finally also because the jar is part of a WAR file which is deployed in JBOSS EAP 6.2 - also tried with WebLogic 12c).
  • The fact that I'm calling it through a stateless EJB means that, by default, there's already a transaction available, so there's no need for me to manage it manually

However, using the above described example simply doesn't persist any data to the db (when calling the EJB saveWhatever method).

What I've also tried tried:

  • calling entityManager.joinTransaction() before calling entityManager.merge(...) (commented line in the DAO code snippet). This gives the error:

    javax.ejb.EJBException: javax.persistence.TransactionRequiredException: No active JTA transaction on joinTransaction call

  • manually calling entityManager.getTransaction().begin() and commit() (before and after entityManager.merge(...). This gives the error:

    javax.ejb.EJBException: java.lang.IllegalStateException: A JTA EntityManager cannot use getTransaction()

So, my question is, please: How do I:

  • make it so I can have a separate DAO class, in a separate JAR, that uses EntityManager without programmatically (manually) dealing with transactions
  • Integrate this DAO-classes-containing jar into a WebApplication that uses EJB so that I can take advantage of JTA and have it auto-manage my transactions (more to the point, I'd like to have the Stateless EJB promised behavior, where JTA takes care of creating a transaction for each of the EJB's method calls)
Was it helpful?

Solution

OK, well, for anyone else experiencing this: if you think everything's correctly setup with your EJBs and JTA, but still JTA transactions don't work, (fail silently, etc), here's how I solved it:

I changed from this persistence unit:

    <!-- bad persistence.xml, JTA transactions don't work -->
<persistence-unit name="pu" transaction-type="JTA">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <jta-data-source>jdbc/jee6Test_mysql_datasource</jta-data-source>
    <!-- <class> tags go here -->
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
        <property name="hibernate.hbm2ddl.auto" value="update" />
        <property name="hibernate.transaction.factory_class" value="org.hibernate.transaction.JTATransactionFactory"/>
    </properties>       
</persistence-unit>

To this one:

<!-- good persistence.xml, JTA transactions work -->
<persistence-unit name="pu" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider> <!-- note change here ->
        <jta-data-source>jdbc/jee6Test_mysql_datasource</jta-data-source>
        <!-- <class> tags go here -->
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
                    <!-- and removal of <property> here -->
        </properties>       
    </persistence-unit>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top