![](/img/trans.png)
[英]EntityManager not injected in Stateless Session Bean with @PersistenceContext
[英]Pass Injected EntityManager to a web session persisted object
将在EJB上创建的Injected EntityManager传递给将返回对象的方法是否安全,然后将该对象保留在Web会话上,以供Web客户端使用?
像这个例子一样:EJB
@Stateless(mappedName = "MyService")
@LocalBean
public class MyService implements MyServiceLocal {
@PersistenceContext(unitName="primary")
private EntityManager em;
/**
* Default constructor.
*/
public MyService() {
}
@Override
public Service newServiceX(User user) {
return new ServiceX(user,em); // here, passing the EntityManager
}
}
之后,我将该服务保留在Web客户端中(使用struts):基本操作
public class YAction extends ActionSupport implements SessionAware{
@Inject
private MyServiceLocal service;
public String execute(){
Service x = service.newServiceX();
persistInCookie("ServiceX",x);
}
public void persistInCookie(String, Object){
// persist
}
}
然后,使用另一个动作://另一个动作
class XAction{
public String useService(){
getService().doSomething();
}
protected Service getService(){
Service service = (Service) getSessionMap().get("ServiceX");
return service;
}
}
使用EntityManager的POJO类ServiceX:
public class ServiceX extends Service{
EntityManager em;
public ServiceX(User user, EntityManager em){
this.em = em;
}
public void doSomething(){
// do something with the EntityManager passed by the EJB
}
}
首先,将被调用的动作是Y动作,以在会话上保留服务,然后,X动作将返回在会话上保留的服务并尝试使用它。
我相信EJB无状态会话Bean可以关闭My EntityManager,而此ServiceX POJO类不能使用它。 这会发生吗? 我在这里找到了类似的问题,但是在这个问题中,EntityManager传递给了一个帮助器类。 我的情况有所不同,因为我想将此对象持久保存在会话cookie中,并在以后使用。
我认为将EntityManager
存储在SessionMap
不是一个好主意。 而且,我什至不认为在EJB容器之外执行EntityManager
操作不是一个好主意。
是否已阅读有关JPA中的事务边界的信息?
缺省情况下,EJB容器使用CMT (容器管理的事务)。 在这种情况下,容器使用每请求一个实体管理器模式 ,这意味着在MyService
一种业务方法开始和结束时(事务在RuntimeException的情况下被提交或回滚),事务开始和结束。 对于整个事务处理时间, EntityManager
与相同的PersistenceContext连接。 事务结束后,容器关闭EntityManager
,这意味着EntityManager
与最近的PersistenceContext断开连接:
// transaction begins
Service x = service.newServiceX();
// transaction ends
如果您要在事务之外执行一些更新/插入操作,那么这可能至关重要。
现在,当您在事务外部调用EntityManager
操作(如find
)时,对于每个操作, EntityManager
都会创建一个新的PersistentContext。 这可能会导致一些问题,因为代表相同记录的两个实体将被视为不同的实体:
// each operation occurs in a separate persistence context, and returns
// a new detached instance
Magazine mag1 = em.find(Magazine.class, magId);
Magazine mag2 = em.find(Magazine.class, magId);
assertTrue(mag2 != mag1);
还有更多文章可供阅读:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.