go4it

just do it

实体的生命周期

一个实体从创建到销毁经历的几个状态:

瞬时状态(transient)----持久化状态(Persisted)-----托管状态(Managed/Attached)-----游离状态(Detached)-----销毁状态(Removed)

1.瞬时状态(transient):

   只是new,但是还没persist到数据库,只是在内存当中。

2.持久化状态(Persisted):

   已经persist到数据库中

3.托管状态(Managed/Attached):

  实体处于持久化上下文当中。将实体转为托管状态的方法:

  (1)调用persist(),实体从瞬时状态到托管状态到持久化状态

  (2)调用find()或Query执行查询:实体从持久化状态到托管状态

  (3)调用refresh():将游离状态的实体重新装载,并转为托管状态

  (4) 调用merge():将游离状态的实体转变为托管状态

 

4.游离状态(Detached):

  实体不在持久化上下文当中。它的属性与数据库中的不同步。

实体有托管状态到游离状态:

(1)一个事务结束,实体超出持久上下文的作用域,变为游离状态。对于无状态的session bean,通常一个方法作为一个持久化上下文的作用域。

(2)当复制实体对象或序列化时,实体将转变为游离状态。通常序列化对象发送在远程调用session bean时。

(3)调用clear()方法时,所有的实体将强制转化为游离状态。

 

5.销毁状态(Removed):

  实体从数据库中删除后的状态。

  em.remove(customer);

实体必须在托管状态下被删除。

@PersistenceContext
protected EntityManager em;
public void deleteCustomer(Integer customerId){
     Customer customer=em.find(Customer.class,customerId);
     em.remove(customer);
 } 
//对比这两个删除方法的不同:
@PersistenceContext
protected EntityManager em;
public void deleteCustomer(Customer customer){
   //将游离状态的customer实体对象变为托管状态
     customer=em.merge(customer);
  //删除实体
     em.remove(customer);
 } 

 

对于第二个方法,如果没有用merge()将游离状态的实体转变为托管状态,而直接remove()则会抛出异常。

 

---------------------------------------------------------------------

实体状态分析:

1.在客户端通过new方式获得的实体是瞬时状态;通过find方法获得的,由于经过序列化,它的状态是游离的。

2.当调用session bean的方法后,进入了EJB的事务管理单元(这里默认事务管理单元为一个EJB方法),这时就进入到了持久化上下文的作用域中

3.在持久化上下文当中,通过find方法获得一个托管状态的实体;通过merge方法将游离的实体转化为托管状态;通过persist方法持久化实体。

4.EJB方法结束,超出持久化上下文的作用域,此时返回的实体类将重新回到游离状态。

posted on 2009-01-23 14:32  cxccbv  阅读(451)  评论(0编辑  收藏  举报

导航