【问题标题】:Problem with EJB + POJO Helpers + EntitiyManagerEJB + POJO Helpers + EntityManager 的问题
【发布时间】:2011-05-05 05:25:07
【问题描述】:

我正在使用 EJB...我执行以下操作,但我不知道为什么注入的 EntityManager 没有按预期工作。

  1. EJB1 调用 EJB2 上的一个方法来写入数据库。
  2. 当 EJB2 返回时,EJB1 向 MDB 发送一条消息。
  3. MDB 调用 EJB3 读取 DB 并执行一些工作。

我的问题是使用@PersistenceContext 注入到所有 3 个 EJB 中的 EntityManager 无法正常工作。在 EJB2 中调用 persist() 不会反映在 EJB3 中注入的 EntityManager 上。 可能有什么问题? 希望我把我的问题说清楚了。 现在使用容器管理的事务。

【问题讨论】:

  • 这是使用 JPA 对吧?我对 JPA 不太熟悉,但我怀疑每个 EJB 都会获得不同的 EntityManager 实例。当您调用persist时,您确定它没有缓存实体并且它已提交到数据库中吗?即使实体在数据库中提交,它也可能不会出现在不同的 EntityManager 实例中,除非您清除其缓存并重新加载所有实体。
  • 是的,使用 JPA。不应该有新的 EntityManager 实例。使用 @PersistenceContext 的注入重用了相同的 EntityManager 实例,其生命周期由容器管理。好吧,我相信会发生这种情况,我不是 100% 确定。
  • 不是每个 EJB 都有自己的 persistence.xml 文件吗?如果是这样,这是否意味着每个 EJB必须 拥有自己的 EntityManager 实例?
  • 对不起,我认为这不正确

标签: jpa jakarta-ee ejb-3.0 ejb jta


【解决方案1】:

我的问题是使用@PersistenceContext 注入到所有 3 个 EJB 中的 EntityManager 无法正常工作。在 EJB2 中调用 persist() 不会反映在 EJB3 中注入的 EntityManager 上。

在 Java EE 环境中,常见的情况是使用 Transaction-Scoped Container-Managed 实体管理器。并且有了这样一个实体管理器,持久性上下文会随着 JTA 事务的传播而传播。

在您的情况下,我怀疑您正在为 EJB3 的方法使用 REQUIRES_NEW 事务属性。所以:

  • 在调用EJB3#bar()时,容器会暂停为EJB2#foo()启动的事务并开始一个新事务
  • EJB3#bar() 调用实体管理器时,将创建一个持久性上下文。
  • 由于为 EJB2#foo() 启动的事务尚未提交,因此更改对新的持久性上下文不“可见”。

PS:你真的在创建新线程吗?如果是,请稍加提醒:这是 EJB 规范所禁止的。

【讨论】:

  • 感谢您的回答。打算调查一下。关于线程...只是将业务逻辑更改为 MDB,避免使用新线程...但问题仍然存在。
  • @nico 正如所暗示的,有关各种 EJB 方法的事务属性的一些细节可能会有所帮助。
  • 我认为 SUPPORTS 类型可能适合我的情况。但是,我认为更改属性时不会产生任何影响。这可能是因为我在休眠配置 xml 中设置了 JDBCTransactionFactory 吗?我应该将其更改为 CMTTransactionFactory 吗?
  • @nico 好吧,我认为你应该提到所有相关的“细节”,比如这个……是的,我会在 Java EE 上下文中使用 CMTTransactionFactory。
  • 对此感到抱歉。我是 java EE 平台的新手,我在旅途中发现它。回到问题...我已经设置了 CMTTransactionFactory 并且属性工作。但我无法让 MDB 中的 entitymanager 与用于写入无状态 EJB 上的 DB 的 entityManager 保持一致,后者也在同一业务方法上发送 jms 消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
  • 2010-11-12
  • 1970-01-01
  • 2011-10-09
相关资源
最近更新 更多