JPA持久化问题

在我的一个JBOSS应用服务器里,有这样三个EJB

 

@Stateless
@Local({A.class})
@Remote({A.class})
public ABean implements A{

    @EJB
    B b;

    @Override
    public void a(){
        T entity = b.find(@Stateless id);b.delete(entity);
        b.delete(entity);
    }
}
 

 

@Local({B.class})
@Remote({B.class})
public BImpl implements B{

    @PersistenceContext
    protected EntityManager entityManager;

    public T find(Long id){
        return entityManager.find(T.class,id);
    }

    public void delete(T entity){
        system.out.println(entityManager.contains(entity));
        entityManager.remove(entity);
    }

}

 

其中ABean,BImpl是无状态会话Bean,都有业务接口分别为A和B。另外T为实体Bean。使用了CMT, 只使用了一个数据源。

 

远程客户端通过JNDI获取A的引用后,调用A.a()方法,最后是报出了异常的,异常原因是“试图删除一个脱管(detached)实体”,而且system.out.println(entityManager.contains(entity))输出是false,即证明了所传给B.delete方法的实体是一个已经脱管的EntityBean;

 

后来对ABean进行了修改,对于ABean中的B接口不利用@EJB来进行容器注入,而是通过JNDI来查找本地接口引用,这个时候,执行A.a()方法是可行的,没有报错,而且system.out.println(entityManager.contains(entity))输出是true,即证明了所传给B.delete方法的实体是一个还受容器管理的受管EntityBean;

 

但是如果ABean中的B接口通过JNDI来查找的不是本地接口,而是远程接口的时候,执行A.a()方法还是会报错的,错误原因还是因为“试图删除一个脱管(detached)实体”,system.out.println(entityManager.contains(entity))输出还是false。

 

通过对上面的实验,可以得出的结论是通过JNDI查找的远程接口中方法所返回的EntityBean是脱管的,而通过JNDI查找的本地接口中方法所返回的EntityBean是受管的。这个可以理解。但是为什么通过@EJB利用容器注入的接口所返回的EntityBean是脱管的?这个真的是无法解释,我也不清楚为什么

 

下面是从网上找到的一些概念

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

一个持久化上下文与一个事务上下文是松耦合的;严格的讲,它隐含的与一个事务会话共存。

 

EntityManager

实体对象由实体管理器进行管理,通过EntityManager和持久化上下文进行交互

实体管理器有两种:

容器类:容器型的实体管理器由容器负责试题管理器之间的协作,Java EE应用服务器提供的就是管理型的实体管理器。

应用程序型:实体管理器的生命周期由应用程序控制,应用程序通过javax.persistence.EntityManagerFactoty的creaeEntityManager创建EntityManager实例

 

如果使用事务范围的容器管理的实体管理器,那么提交事务、回滚事务、清除持久化上下文、关闭实体管理器、以及序列化实体或按值传递一个实体(如在分布式应用中,通过远程接口传递等)都会产生脱管实体。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

其实依赖注入只工作在本地命名服务中,不能注入远程服务器的对象。在实际应用中,EJB可能会使用到其他EJB或资源,这时必须通过JNDI查找或注入注释。因些上面通过@EJB来注入接口存根的话,应该是本地的才对,但是结果却跟通过JNDI获取到的本地接口执行结果不一样,真是不清楚怎么回事了。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值