我正在尝试使用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>