5 Replies Latest reply on May 28, 2012 9:00 PM by oman002

    Multiple EntityManagers with different persistence units

    pi4630

      I've defined two persistence units in my persistence.xml: each one with its own data source (one points to an Oracle database on which I do reads, the other points to the HsqlDB I use to write).

      Entity beans are mapped (by annotations) correctly. In my SLSB I inject two distinct EntityManagers, that refer to the relative name of the persistence units.

       

      In my business method, I do a db read using the EntityManager pointing to the OracleDB and then I call a private method, where I instantiate a new entity which corresponds to a table on my HsqlDB. I then pass this object to myHsqlDbEMan.persist() method at the end of the private method.

      Soon after the methods are terminated (and the server is committing changes to the database), I get the following error:

       

      {noformat}ERROR [org.hibernate.util.JDBCExceptionReporter] (WorkerThread#0[127.0.0.1:48655]) Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: 0:ffff7f000101:126a:4e5def22:c status: ActionStatus.ABORT_ONLY >); - nested throwable: (org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: 0:ffff7f000101:126a:4e5def22:c status: ActionStatus.ABORT_ONLY >))

      2011-08-31 10:22:49,884 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] (WorkerThread#0[127.0.0.1:48655]) Could not synchronize database state with session: org.hibernate.exception.GenericJDBCException: Cannot open connection{noformat}

       

       

      How do I handle two different persistence contexts? I've tried to refactor my SB as Stateful and extend the persistence context of both persistence units, but that didn't work (returned same error). I also tried to refactor that writeToDb() to another SessionBean and use the HsqlDB context only there and invoke the method from my other bean, but that didn't work either.

      I presumed that by using the different EntityManager, the AS would know about which context the method is in.

       

       

      Thanks in advance,

        • 1. Re: Multiple EntityManagers with different persistence units
          wdfink

          For me it sounds principal right what you do first.

          But I recommend to use a different database not the HSQLDB.

           

          To analyze your problem you should attach the related WARN message. Maybe it helps if you set 'org.hibernate' to TRACE for your test to see more.

          A stateful session with extended persistence context looks not correct because this looks like a typical stateless call to me.

          • 2. Re: Multiple EntityManagers with different persistence units
            pi4630

            Sorry for my late reply, this is what I see in the log

            {noformat}

            WARN  [org.hibernate.util.JDBCExceptionReporter] (WorkerThread#0[127.0.0.1:34061]) SQL Error: 0, SQLState: null

            2011-09-06 15:28:39,327 ERROR [org.hibernate.util.JDBCExceptionReporter] (WorkerThread#0[127.0.0.1:34061]) Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: 0:ffff7f000101:126a:4e661ff4:c status: ActionStatus.ABORT_ONLY >); - nested throwable: (org.jboss.resource.JBossResourceException: Could not enlist in transaction on entering meta-aware object!; - nested throwable: (javax.transaction.SystemException: java.lang.Throwable: Unabled to enlist resource, see the previous warnings. tx=TransactionImple < ac, BasicAction: 0:ffff7f000101:126a:4e661ff4:c status: ActionStatus.ABORT_ONLY >))

            2011-09-06 15:28:39,328 ERROR [org.hibernate.event.def.AbstractFlushingEventListener] (WorkerThread#0[127.0.0.1:34061]) Could not synchronize database state with session: org.hibernate.exception.GenericJDBCException: Cannot open connection{noformat}

             

            (I hope I've formatted this correctly btw.)

             

            The connection to Hypersonic DB is just for testing purposes. I'd assume the AS switches connection as soon as the private method of the SLSB ends and commits it (it is still inside the public method it implements from the interface).

            • 3. Re: Multiple EntityManagers with different persistence units
              wdfink

              Looks like that the second connection should enlist the Tx and the Tx manager is in state 'Abort', mean there are Exceptions before.

              Do you see what SQL's are send to DB? Maybe you can try it isolated.

              Unfortunately sometimes the error message of SQL is hidden (e.g. during prepare/commit).

               

              Do you have a very simple example that fail?

              • 4. Re: Multiple EntityManagers with different persistence units
                pi4630

                Yes, the example is quite simple. I shall attach the source code of the SLSB.

                 

                I tried to switch on SQL output in the persistence.xml (hibernate property value), but that didn't work. Here's my persistence.xml

                 

                {code:xml}

                <?xml version="1.0" encoding="UTF-8"?>

                <persistence 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_1_0.xsd"

                          version="1.0">

                          <persistence-unit name="SPADEV">

                                    <jta-data-source>java:/OracleDS</jta-data-source>

                                    <properties>

                                              <property name="hibernate.show_sql" value="false" />

                                              <property name="hibernate.format_sql" value="false" />

                                              <!-- <property name="hibernate.dialect" value="it.bz.tol.oracle.hibernate.OracleSpatialDialect"

                                                        /> -->

                                              <property name="hibernate.dialect"

                                                        value="org.hibernatespatial.oracle.OracleSpatial10gDialect" />

                                    </properties>

                          </persistence-unit>

                          <persistence-unit name="MERCURIUS">

                                    <jta-data-source>java:/DefaultDS</jta-data-source>

                                    <properties>

                                    <property name="hibernate.show_sql" value="true" />

                                    <property name="hibernate.format_sql" value="true" />

                                    </properties>

                          </persistence-unit>

                </persistence>{code}

                • 5. Re: Multiple EntityManagers with different persistence units
                  oman002

                  Sounds like you are trying to enlist multiple one-phase only resources (ie: local-tx-datasources) in a transaction. You'll need to use XA transaction resources or see the other recommendations here: https://community.jboss.org/wiki/Multiple1PC