jpa + ejb如何为多个请求保持实体附加(托管)?

时间:2015-07-04 19:59:27

标签: jpa ejb

这是我到目前为止所尝试的内容。

我向我的单身人士做了两次请求。第一个请求由方法firstRequest处理,它更改数据库。第二个请求由方法secondRequest处理,但它不会更改数据库。

@Singleton
public class App{

@Inject DaoHuman daoHuman;
Human human;    

public void firstRequest(){
    human= daoHuman.findById(1);
    human.setAge(3);
}

public void secondRequest(){
    human.setAge(99);
}
@Stateful
public class DaoHuman{
    @PersistenceContext(unitName = "myPU", type=PersistenceContextType.EXTENDED)
    private EntityManager em;

我的问题是第一次请求后实体变得分离(非托管)。所以它永远不会得到第二个请求。

1 个答案:

答案 0 :(得分:0)

你有一个为你的有状态会话Bean定义的扩展持久化上下文,实际上在daoHuman.findById(1)之后(未显示此代码,但我认为它是em.find(Humand.class, id))被调用,人类ID = 1 1将成为一个托管实体,并由扩展的持久化上下文跟踪。

此外,因为您有一个扩展持久性上下文,所以此上下文将持续有状态会话Bean的生命周期,并且在多个客户端调用(对话)期间将保持对人类实体的管理。 p>

这一切都很好。但是,您的Singleton是无状态的,因此当您发出第二个请求时,人类不会被初始化。

您还必须记住,在对定义了EntityManager的有状态会话Bean进行调用时,扩展持久性上下文将仅与当前事务关联。 secondRequest()不会发生这种情况,因此当事务完成时,不会将持久化上下文刷新/持久保存到数据库。

跨多个调用使用托管实例的一种简单方法是在首次初始化bean时将实体存储在有状态会话Bean实例上。 我在下面的代码中保留了单例/有状态会话bean结构。根据要求,我很想在会话bean上进行实体更新。

@Singleton
public class App{

@Inject DaoHuman daoHuman;
Human human;    

    Public void init(int humanId){
        daoHuman.init(humanId);
}

    public void firstRequest(){
// Making the call to daoHuman.getHuman() both returns the mnaged entity and
// causes the persistence context to be associated with the current  
// transation, so when this method call ends, the context will be 
// Depending on requirementsflushed/committed.
        human= daoHuman.getHuman();
        human.setAge(3);
}

    public void secondRequest(){
        human= daoHuman.getHuman();
        human.setAge(99);
}

@Stateful
public class DaoHuman{
@PersistenceContext(unitName = "myPU", type=PersistenceContextType.EXTENDED)
private EntityManager em;
Human human;

    public void Init(int humanId){  
// em.find() will ensure the found entity becomes managed - part of the
// persistene context, placing it on the instance variable ensures    
// the managed entity is available over multple client invocatons (converstion)
        human = em.find(Human.class, humanId)
}
    public Human getHuman(){
        return human;
}
相关问题