Unnable to use multiple JTA EntityManager at the same time

81 Views Asked by At

Trying to query data from legacy database (with different datasource) to current database, but got two exceptions in two scenarios.

I've got an implementation like this:

class A {

  @PersistenceContext(unitName = "EPU")
  EntityManager schemaEntityManager;

  @PersistenceContext(unitName = "ELegacyPU")
  EntityManager oldSchemaEntityManager;

  void init() {
     queryFromDatabase();
     // check if it is empty, if true then query from legacy
     queryFromLegacyDatabase();
     recreateLegacyInCurrentDatabase();
  }

  List<E> queryFromDatabase() {
    // query from schemaEntityManager
  }
  
  List<ELegacy> queryFromOldDatabase() {
    // query from oldSchemaEntityManager
  }

  void recreateLegacyInCurrentDatabase() {
    // records -> schemaEntityManager.merge()
  }
}

While I'm trying to run this with @Translational over recreateLegacyInCurrentDatabase method, then got exception from this method (cannot found any valid info over hibernate's TRACE log-level):

javax.persistence.TransactionRequiredException: WFLYJPA0060: Transaction is required to perform this operation (either use a transaction or extended persistence context)
    at [email protected]//org.jboss.as.jpa.container.AbstractEntityManager.transactionIsRequired(AbstractEntityManager.java:880)
    at [email protected]//org.jboss.as.jpa.container.AbstractEntityManager.merge(AbstractEntityManager.java:567)

While I'm trying to run this with @Translational over only class or over only queryFromDatabase/queryFromOldDatabase method or over any of this two cases + recreateLegacyInCurrentDatabase, then got exception from queryFromOldDatabase (cannot found any valid info over hibernate's TRACE log-level):

javax.persistence.PersistenceException: org.hibernate.exception.GenericJDBCException: could not prepare statement
    at [email protected]//org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154)
    at [email protected]//org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1575)
    at [email protected]//org.hibernate.query.Query.getResultList(Query.java:132)
    at [email protected]//org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getResultList(CriteriaQueryTypeQueryAdapter.java:74)
...
Caused by: org.hibernate.exception.GenericJDBCException: could not prepare statement
...
Caused by: java.sql.SQLException: IJ031070: Transaction cannot proceed: STATUS_MARKED_ROLLBACK

I use JTA configured under persistence.xml & trying not to use RESOURCE_LOCAL instead of this or there is no option to do this without RESOURCE_LOCAL configuration in persistence.xml?

1

There are 1 best solutions below

0
y07k2 On

I just used something like this (also for old PU):

EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(getPUName());
EntityManager entityManager = entityManagerFactory.createEntityManager();

and in persistence.xml we need to change standard JTA to RESOURCE_LOCAL and jta-data-source property to non-jta-data-source property:

<persistence-unit name="YourPU" transaction-type="RESOURCE_LOCAL">
  <non-jta-data-source>java:jboss/datasources/YourDS</non-jta-data-source>
</persistence-unit>

So while using RESOURCE_LOCAL we need to secure two things, transaction:

entityManager.getTransaction().begin();
// code
entityManager.getTransaction().commit();

and after all remember to close things up:

entityManagerFactory.close();