如何让 Spring bean 和 EJB(它们都在 TomEE 容器中)使用公共持久性上下文?
我正在尝试将几个 EJB 组件合并到一个主要是 Spring 应用程序中。最终一切都将是 EJB3 或 Spring,但在可预见的未来,我生活在一个混合世界中。
- 数据源在应用程序的 resources.xml 文件中定义
- PersistenceUnit 在引用数据源的 persistence.xml 文件中定义
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"/>
Spring 和 EJB 组件可以轻松找到事务管理器、实体管理器或数据源;任何完全是 Spring 或完全 EJB 的东西都可以正常工作。但...
在某些情况下,事务必须在 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 的事务的内容。