3

如何让 Spring bean 和 EJB(它们都在 TomEE 容器中)使用公共持久性上下文?

我正在尝试将几个 EJB 组件合并到一个主要是 Spring 应用程序中。最终一切都将是 EJB3 或 Spring,但在可预见的未来,我生活在一个混合世界中。

  1. 数据源在应用程序的 resources.xml 文件中定义
  2. PersistenceUnit 在引用数据源的 persistence.xml 文件中定义
  3. Spring 在 applicationContext.xml 文件中访问容器事务管理器和 EntityManagerFactory 如下:

    <tx:annotation-driven mode="aspectj"
        transaction-manager="transactionManager" />
    
    <bean id="transactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
    <property name="transactionManagerName"
            value="java:comp/env/comp/TransactionManager"/>
    </bean>
    
    <jee:jndi-lookup id="entitiesEntityManagerFactory" 
         jndi-name="persistence/entitiesPersistenceUnit"
         resource-ref="true"/>
    
  4. Spring 和 EJB 组件可以轻松找到事务管理器、实体管理器或数据源;任何完全是 Spring 或完全 EJB 的东西都可以正常工作。但...

  5. 在某些情况下,事务必须在 EJB 中启动,然后传播到 Spring bean 上调用的方法,此时 Spring bean 抱怨它拥有非托管实体。我用 注释 EJB 中的启动方法@TransactionAttribute和 Spring Bean 中的接收方法@Transactional(propagation=Propagation.Mandatory);Spring bean 不会抱怨不在事务上下文中,但不知何故,持久性上下文不遵循,通过this.entityManager.contains(this)返回 false 进行验证。

问题似乎在于 Spring 和 OpenEJB 处理实体管理器注入的方式。如果我在 EJB 和 Spring bean 中包含相同的代码:

@PersistenceContext
EntityManger em;

在 EJB 中,em注入了一个实例org.apache.openejb.persistence.JtaEntityManager

而在 Spring 中,em注入的内容如下所示:

shared EntityManager proxy for target factory [org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory@1ca24fe7]

和 Proxy都JtaEntityManager包含相同的底层实例org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory

我已经阅读了有关 Spring / EJB 集成的所有内容,但没有找到任何具体处理共享持久性上下文或从 EJB 到 Spring bean 的事务的内容。

4

0 回答 0