我们有一些JavaEE5无状态EJB将注入的EntityManager传递给它的助手。
这安全吗?到目前为止,它运行得很好,但是我发现一些甲骨文文档指出它的EntityManager实现是线程安全的。现在我想知道我们直到现在才有问题的原因,仅仅是因为我们使用的实现碰巧是线程安全的(我们使用Oracle)。
@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是线程不安全的,容器就必须这样做。
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环境”。
发布于 2010-03-08 08:49:32
我使用了类似的模式,但助手是在@PostConstruct中创建的,注入的实体管理器作为参数在构造函数中传递。每个EJB实例都有自己的助手,那时线程安全得到了保证。
我也有一个变体,如果没有注入实体管理器(因为EJB没有完全使用它),所以助手必须用InitialContext查找它。在这种情况下,持久化上下文仍然必须在带有@PersistenceContext的父EJB中“导入”。
@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节略为涵盖了这一主题。
发布于 2010-03-08 07:13:01
我一直在使用帮助方法,并在那里传递了EntityManager,这是完全可以的。
因此,我建议在需要时将它传递给方法,或者让助手本身成为一个bean,注入它(使用@EJB),并在那里注入EntityManager。
发布于 2011-10-28 11:31:49
就我个人而言,我不希望将实体管理器传递给构造函数或方法中的所有POJO。特别是对于POJO数量很大的非平凡程序。
我将尝试创建POJO/HelperClasses来处理EntityManager返回的实体,而不是直接使用实体管理器。
如果不可能,我想我会创建一个新的EJB。
https://stackoverflow.com/questions/2399769
复制相似问题