我正在尝试将 OpenJPA Slice 用作 JBoss 4.0.5 (EJB 2.1) 应用程序服务器中的一个类的持久性机制,但遇到了一些问题。
在 J2SE 设置中,以下代码(创建一个 EntityManager,使用它,关闭它,创建一个新的,使用它关闭它)工作正常。
EntityManagerFactory factory = Persistence.createEntityManagerFactory("my_persistence_unit");
EntityManager em = factory.createEntityManager();
Query q = em.createQuery("select m from mytable m");
List result = q.getResultList();
// ... do something with result
em.close();
em = factory.createEntityManager();
q = em.createQuery("select m from myothertable m");
result = q.getResultList();
// ... do something with result
em.close();
但是如果我尝试在 StatelessSessionBean 中做同样的事情(再次:EJB 2.1)
// the entity manager FACTORY is a static variable defined elsewhere
EntityManager em = FACTORY.createEntityManager();
Query q = em.createQuery("select m from mytable m");
List result = q.getResultList();
// ... do something with result
em.close();
em = FACTORY.createEntityManager();
q = em.createQuery("select m from myothertable m");
result = q.getResultList();
// ... do something with result
em.close();
...我在第二次查询执行时遇到异常:
<openjpa-1.0.1-r420667:592145 fatal user error> org.apache.openjpa.persistence.InvalidStateException: The context has been closed.
如果我的 SessionBean 方法中只有一个查询并且我远程调用它两次,也会发生同样的事情。第一次调用工作正常,但第二次调用会抛出相同的异常。
似乎 SessionBean 中的所有查询都是针对会话 bean 中创建的第一个 EntityManager 的上下文执行的。如果我不在第一个 EntityManager 上调用 close(),一切正常。
我很困惑为什么 SessionBeans 和 JPA EntityManagers 之间有任何干扰,因为 JBoss 4 太老了,它不应该对 JPA 有任何了解。
这是 J2SE 设置的 persistence.xml:com.mycompany.MyEntity
<properties>
<property name="openjpa.BrokerFactory" value="slice"/>
<property name="openjpa.slice.Names" value="One,Two"/>
<property name="openjpa.slice.Master" value="One"/>
<property name="openjpa.slice.Lenient" value="true"/>
<property name="openjpa.slice.One.ConnectionURL" value="jdbc:mysql://localhost/jpa_test_1"/>
<property name="openjpa.slice.Two.ConnectionURL" value="jdbc:mysql://localhost/jpa_test_2"/>
<property name="openjpa.slice.DistributionPolicy" value="com.mycompany.RandomDistributionPolicy"/>
<property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
<property name="openjpa.ConnectionUserName" value="user"/>
<property name="openjpa.ConnectionPassword" value="password"/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
<!-- -->
</properties>
</persistence-unit>
这是 JBoss 设置的 persistence.xml:
<persistence-unit name="my_persistence_unit" transaction-type="RESOURCE_LOCAL">
<class>com.mycompany.MyEntity</class>
<properties>
<property name="openjpa.BrokerFactory" value="slice"/>
<property name="openjpa.slice.Names" value="One"/>
<property name="openjpa.slice.Master" value="One"/>
<property name="openjpa.slice.Lenient" value="true"/>
<property name="openjpa.ConnectionUserName" value="user"/>
<property name="openjpa.ConnectionPassword" value="password"/>
<property name="openjpa.slice.One.ConnectionURL" value="jdbc:mysql://localhost/jpa_test_1"/>
<property name="openjpa.slice.One.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
<property name="openjpa.slice.Two.ConnectionURL" value="jdbc:mysql://localhost/jpa_test_2"/>
<property name="openjpa.slice.Two.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
<property name="openjpa.slice.ThreadingPolicy" value="cached"/>
<property name="openjpa.slice.DistributionPolicy" value="com.mycompany.RandomDistributionPolicy"/>
<property name="openjpa.jdbc.DBDictionary" value="mysql"/>
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
<property name="openjpa.Log" value="DefaultLevel=INFO, Runtime=TRACE, Tool=INFO, SQL=TRACE"/>
<property name="openjpa.jdbc.QuerySQLCache" value="false"/>
</properties>
</persistence-unit>