无法在会话Bean方法中创建和关闭多个实体管理器

时间:2013-08-28 21:27:04

标签: jpa jboss openjpa

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

0 个答案:

没有答案