我正在将应用程序中的实体bean从EJB 2.0升级到3.0版本。我在weblogic服务器(10.3.0)上使用openjpa版本1.2.2,事务类型将是JTA。
在提交持久化实体的交易后,我面临以下错误:
javax.transaction.SystemException:非法状态(预期: 预先制备)。 BEA1-0A15322BC6A35D331713 at weblogic.transaction.internal.TransactionImpl.abortUnsync(TransactionImpl.java:1134) 在 weblogic.transaction.internal.ServerTransactionImpl.globalPrepare(ServerTransactionImpl.java:2172) 在 weblogic.transaction.internal.ServerTransactionImpl.internalCommit(ServerTransactionImpl.java:270) 在 weblogic.transaction.internal.ServerTransactionImpl.commit(ServerTransactionImpl.java:230) 在 weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:283) 在 weblogic.transaction.internal.TransactionManagerImpl.commit(TransactionManagerImpl.java:277) 在 com.bt.cp.entities.EntityBeansMultiThreadTest $ Loader.call(EntityBeansMultiThreadTest.java:104) 在 com.bt.cp.entities.EntityBeansMultiThreadTest $ Loader.call(EntityBeansMultiThreadTest.java:78) at java.util.concurrent.FutureTask $ Sync.innerRun(FutureTask.java:303) 在java.util.concurrent.FutureTask.run(FutureTask.java:138)at java.util.concurrent.ThreadPoolExecutor中的$ Worker.runTask(ThreadPoolExecutor.java:885) 在 java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:907) 在java.lang.Thread.run(Thread.java:619)
以下是导致此错误的代码段:
public Boolean call() throws Exception {
EntityManager entityManager = entityManagerSingleton.createEntityManager();
UserTransaction tx = entityManagerSingleton.createTransaction();
try {
tx.begin();
// Join the EntityManager operations to this UserTransaction
entityManager.joinTransaction();
entityManager.persist(new Party());
tx.commit();
} catch(Exception e) {
e.printStackTrace()
}
return true;
}
下面是我的persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="testDataSource" transaction-type="JTA">
<jta-data-source>testDataSource</jta-data-source>
<class>test.Party</class>
<class>
.........................
</class>
<properties>
<property name="openjpa.QueryCache" value="true(CacheSize=1000)"/>
</properties>
</persistence-unit>
</persistence>
openjpa 1.1.0版(weblogic 10.3.0的一部分)中没有出现此错误。但是,版本1.1.0(https://issues.apache.org/jira/browse/OPENJPA-466)存在一个主要错误,因此我使用的是版本1.2.2。
如何解决此问题?任何人都对此有任何指示。任何帮助表示赞赏。
答案 0 :(得分:1)
您声明OpenJPA存在错误。我不会根据您发布的内容提出索赔。事实上,“SystemException:Illegal state”似乎完全是WebLogic的堆栈;我没有在堆栈上看到OpenJPA。如果堆栈有更多,并且发生OpenJPA异常,请在此处发布。否则,我认为你最好将其视为一个WebLogic问题,特别是它们的Tx处理。此外,如果可能,您应该转移到更新的OpenJPA,例如2.2.x或2.4.x作为1.1.x和1.2.x非常陈旧(尽管WebLogic可能与某个JPA / OpenJPA版本“硬连线”,因此您需要先与它们核对)。接下来,我确实想知道潜在的线程问题。我可能制作了太多的名字,但我看到你有一个“entityManagerSingleton.createEntityManager”和“EntityBeansMultiThreadTest”,以及堆栈似乎从一个线程池开始。我建议你认真看看任何线程问题,并确保多个线程不使用EntityManager! JPA规范清楚地表明EntityManager不是线程安全的。 EntityManagerFactory是线程安全的,但不是EntityManager。如果两个或多个线程使用相同的EntityManager,并且由于您的代码显示您正在加入并提交Tx,则线程可能很容易相互踩踏并导致错误(非法)Tx状态。最后,由于您使用的是应用程序管理的实体管理器,因此您需要处理EntityManager的生命周期,这意味着您需要在完成后关闭EntityManager。在上面的代码中,我没有看到你在'entityManager'实例上调用'close'。如果不这样做,您可能会使EntityManager处于无法进行GC的状态。是的,'entityManager'实例的范围是方法本身,但是,JPA提供程序仍然可以保留EntityManager的数据结构,因为它不知道EntityManager不再使用(即因为它从未被告知'关闭'它)。
谢谢,
希斯