繁体   English   中英

将Injected EntityManager传递到Web会话持久对象

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM