首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将注入的EntityManagers传递给EJB的助手类并使用它可以吗?

将注入的EntityManagers传递给EJB的助手类并使用它可以吗?
EN

Stack Overflow用户
提问于 2010-03-08 07:01:11
回答 3查看 5.5K关注 0票数 6

我们有一些JavaEE5无状态EJB将注入的EntityManager传递给它的助手。

这安全吗?到目前为止,它运行得很好,但是我发现一些甲骨文文档指出它的EntityManager实现是线程安全的。现在我想知道我们直到现在才有问题的原因,仅仅是因为我们使用的实现碰巧是线程安全的(我们使用Oracle)。

代码语言:javascript
复制
@Stateless
class SomeBean {
    @PersistenceContext
    private EntityManager em;

    private SomeHelper helper;

    @PostConstruct
    public void init(){
        helper = new SomeHelper(em);
    }

    @Override
    public void business(){
        helper.doSomethingWithEm();
    }

}

其实这很有道理..。如果EntityManager是线程不安全的,容器就必须这样做。

代码语言:javascript
复制
inercept business()
this.em = newEntityManager();
business();

它不会传播到它的助手类。

如果是,在这种情况下,最佳做法是什么?传递EntityManagerFactory而不是EntityManager?

编辑:这个问题非常有趣,所以如果您对这个问题感兴趣,您可能也想查看这个问题:

编辑:更多信息。ejb3.0规范

4.7.11不可重入实例容器必须确保在任何时候只有一个线程可以执行实例。如果一个客户端请求在实例执行另一个请求时到达,容器可能会将javax.ejb.ConcurrentAccessException抛给第二个client24。如果使用EJB2.1客户端视图,容器可能会将java.rmi.RemoteException抛给第二个请求(如果客户端是远程客户端),或者javax.ejb.EJBException (如果客户机是本地客户端)。25注意会话对象只支持单个客户端。因此,如果两个客户端试图调用同一个会话对象,则将是应用程序错误。此规则的一个含义是,应用程序不能对会话bean实例进行回送调用。

和,

4.3.2依赖注入会话bean可以使用依赖注入机制来获取对其环境中的资源或其他对象的引用(参见第16章“企业Bean环境”)。如果会话bean使用依赖项注入,容器在创建bean实例之后以及在bean实例调用任何业务方法之前注入这些引用。如果声明了对SessionContext的依赖关系,或者bean类实现了可选的SessionBean接口(参见4.3.5节),此时也会注入SessionContext。如果依赖项注入失败,bean实例将被丢弃。在EJB3.0API下,bean类可以通过依赖注入获得SessionContext接口,而不必实现SessionBean接口。在本例中,资源注释(或资源-env-ref部署描述符元素)用于表示bean对SessionContext的依赖。参见第16章,“企业Bean环境”。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-08 08:49:32

我使用了类似的模式,但助手是在@PostConstruct中创建的,注入的实体管理器作为参数在构造函数中传递。每个EJB实例都有自己的助手,那时线程安全得到了保证。

我也有一个变体,如果没有注入实体管理器(因为EJB没有完全使用它),所以助手必须用InitialContext查找它。在这种情况下,持久化上下文仍然必须在带有@PersistenceContext的父EJB中“导入”。

代码语言:javascript
复制
@Stateless 
@PersistenceContext(name="OrderEM") 
public class MySessionBean implements MyInterface { 
  @Resource SessionContext ctx; 
  public void doSomething() { 
     EntityManager em = (EntityManager)ctx.lookup("OrderEM"); 
     ... 
  } 
}

但是,实际上注入它(即使EJB不使用它)要比查找它要容易,特别是为了可测试性。

但是,回到您的主要问题,我认为注入或查找的实体管理器是一个包装器,它将转发到绑定到事务的底层活动实体管理器。

希望能帮上忙。

编辑

规范中的第3.3节和第5.6节略为涵盖了这一主题。

票数 2
EN

Stack Overflow用户

发布于 2010-03-08 07:13:01

我一直在使用帮助方法,并在那里传递了EntityManager,这是完全可以的。

因此,我建议在需要时将它传递给方法,或者让助手本身成为一个bean,注入它(使用@EJB),并在那里注入EntityManager

票数 2
EN

Stack Overflow用户

发布于 2011-10-28 11:31:49

就我个人而言,我不希望将实体管理器传递给构造函数或方法中的所有POJO。特别是对于POJO数量很大的非平凡程序。

我将尝试创建POJO/HelperClasses来处理EntityManager返回的实体,而不是直接使用实体管理器。

如果不可能,我想我会创建一个新的EJB。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2399769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档