java - 通过无状态本地 EJB 从有状态 EJB 检索实体(使用每次对话的长对话)

标签 java transactions ejb entitymanager

首先,我有一个无状态 bean,它执行简单的检索,如下所示。

@Stateless
@LocalBean
public A {
    @PersistenceContext
    private EntityManager em;

    public MyEntity retrieveMethod(){
        em.createQuery(...).getSingleResult();
    }
}

我有一个有状态的 bean 用于管理与远程客户端的长时间对话,它看起来像这样:

@Statefull
@LocalBean
@TransactionAttribute(NOT_SUPPORTED)
public class B implements BRemote {
    @PersistenceContext(type = EXTENDED)
    private EntityManager em;

    @EJB
    A a;

    public void start(){
        OtherEntity oe = new OtherEntity();
        oe.setRelationMyEntitie(this.a.retrieveMethod());

        em.persist(oe);
    }

    @TransactionAttribute(REQUIRED)
    public void end(){
        em.flush();
    }
}

执行 em.persist(oe) 时出现问题。 oe 引用了另一个 EntityManager 加载的 MyEntity 实例。所以他们不知道它在提示持久分离的实体。

我想知道有什么方法可以避免这个问题。如果没有直接的解决方案,最好采用什么模式?


编辑:我不想在 start() 上使用事务,因为在实际应用程序中,statefull bean 用于实现需要立即持久化的复杂实体模型。我尝试在此处描述的 http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html/transactions.html#transactions-basics-apptx 中设置称为每次对话 session 的模式.因此,如果我理解正确,解决方案是“在 bean B 的 start() 方法中使用事务”,但如果我这样做,在方法结束时,内容会刷新到数据库,这不是我想要的.

我能看到的其他解决方案是在 B 的 EntityManager 中获取 MyEntity,因此进行合并或 em.find() 或将 retrieveMethod 委托(delegate)给某些 DAO 样式类,使用 em in 参数,在 bean A 中,对 DAO 做一个简单的委托(delegate),在 bean B 中,直接调用 DAO。

关于什么是最佳方法有什么想法吗?

最佳答案

这是一个很有趣的问题。这个设置看起来绝对合理,但难点在于交易的两个“自动”行为:

  • 与调用链中的其他bean共享资源
  • 当持久性上下文与事务无关时自动持久化排队的操作

这变得更加困难,因为您要共享的资源正是实体管理器。否则,您可以使用 EJB 中的第三种变体,称为“应用程序管理”实体管理器。这可以通过编程方式与事务关联(使用 em.join()),而不管业务方法是否在事务中。

您可能需要在没有交易的情况下共享,或者阻止 em 在交易关联时自动刷新。据我所知,两者都是 EJB 中缺少的功能。 也许管理扩展 em 的应用程序不执行自动刷新,但我不会屏住呼吸。

但是更手动的方法呢?暂时不要调用 em.persist(),而是使用一个单独的列表来存储对在对话期间需要保留的任何实体的引用。

然后在关闭方法中迭代该列表并调用 em.persist()。

附言

另一种选择:如果您使用 em.merge() 而不是 em.persist() 会怎样? Merge 是一种多功能方法,它既可以更新也可以插入,并且不关心实体是否被附加。如果实体永远不会在 A 和 B 之间分离,那就更好了,但这可能是一个实用的解决方案。

关于java - 通过无状态本地 EJB 从有状态 EJB 检索实体(使用每次对话的长对话),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8840746/

相关文章:

hibernate - Grails 编程式事务处理

jakarta-ee - MDB 和 JMS 之间的区别

Java SSL 客户端无自签名证书

Java Spring : Return large string in rest api

c# - 使用 WCF 服务行为属性设置为 ConcurrencyMode.Multiple 和 InstanceContextMode.PerCall 时是否可能出现并发问题?

java - 将 glArrayElement 与 LWJGL 结合使用

c# - 在事务中截断 Oracle 临时表,截断 *所有* 临时表

java - 如何查找类的对象

java - 错误 : JMX connector server communication error: service:jmx:rmi when stopping/shutdown Tomcat

java - 使用 Jackson 创建包含数组和自定义字段的有效 JSON