尝试从旧数据库(具有不同数据源)查询数据到当前数据库,但在两种情况下出现两个异常。
我有这样的实现:
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()
}
}
当我尝试在
@Translational
方法上使用 recreateLegacyInCurrentDatabase
运行此方法时,然后从该方法中得到异常(无法在 hibernate 的 TRACE 日志级别上找到任何有效信息):
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)
当我尝试仅在类
或上使用
@Translational
运行此程序时,仅在queryFromDatabase
/queryFromOldDatabase
方法或上运行这两种情况+recreateLegacyInCurrentDatabase
中的任何一个,然后从queryFromOldDatabase
中得到异常(无法通过 hibernate 的 TRACE 日志级别找到任何有效信息):
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
我使用在
persistence.xml
下配置的JTA,并且尝试不使用RESOURCE_LOCAL来代替它,或者没有选项可以在persistence.xml
中没有RESOURCE_LOCAL配置的情况下执行此操作?
我只是用了这样的东西(也适用于旧PU):
EntityManagerFactory entityManagerFactory = createEntityManagerFactory(getPUName());
EntityManager entityManager = entityManagerFactory.createEntityManager();
并且在
persistence.xml
中,我们需要将标准 JTA
更改为 RESOURCE_LOCAL
并将 jta-data-source
属性更改为 non-jta-data-source
属性:
<persistence-unit name="YourPU" transaction-type="RESOURCE_LOCAL">
<non-jta-data-source>java:jboss/datasources/YourDS</non-jta-data-source>
</persistence-unit>
因此,在使用
RESOURCE_LOCAL
时,我们需要确保两件事,交易:
entityManager.getTransaction().begin();
// code
entityManager.getTransaction().commit();
毕竟记得关闭事情:
entityManagerFactory.close();