java jpa中year函数_Java持久性API(JPA)第7讲——实体生命周期及生命周期回调方法...

源贴地址:http://blog.csdn.net/javaeeteacher/archive/2007/06/25/1665345.aspx

目标与主要内容:

u掌握实体的生命周期;

u掌握实体的生命周期的转换;

u掌握实体的生命周期回调方法的使用;

1、实体的生命周期

参考书上362页。

4种状态:

u新建:没有持久标识,并且没有与上下文环境关联。

u分离的:具有持久标识,并且没有与持久上下文环境关联。

u管理的:具有持久标识,并且与持久上下文环境关联。

u删除的:具有持久标识,并且与持久上下文环境关联,但是准备从数据库中删除。

2、对实体的操作

对实体的各种操作可以改变实体的状态,对这些操作分别介绍如下:

2.1持久化实体实例

通过persist方法或者被级联persist方法完成。例如可以直接持久化一个订单项,也可以通过持久化订单,该操作可以级联到订单项。

persist操作结果如下:

u如果是新的实体,则会变成管理的;

u如果是被管理实体,则该操作被忽略;

u如果是删除的实体,则将重新变成被管理的;

u如果是分离的实体,会抛出异常;

u如果关系中声明的级联操作包括CascadeType.PERSIST,则会把级联的实体持久化。

2.2删除实体

通过remove方法或者被级联的remove方法完成。例如可以直接删除一个订单项,也可以通过删除订单来删除订单项。

Remove操作的结果如下:

u如果是新的实体,则该操作被忽略;

u如果是被管理实体,则会变成删除的;

u如果是删除的实体,则该操作被忽略;

u如果是分离的实体,会抛出异常;

u事务提交的时候或者作为flush操作的结果,删除的实体将从数据库中删除。

2.3同步到数据库

通常自动完成,也可以使用flush操作完成。

flush操作的结果如下:

u如果实体是管理的实体,将被同步到数据库;

u如果是实体是删除的实体,将从数据库中删除掉。

2.4分离实体

分离的实体可能来自:

u事务提交;

u事务回滚;

u删除持久上下文;

u管理实体管理器;

u串行化一个实体或者通过值传递参数;

在第6讲中,在Servlet中创建的Ordertable对象作为参数传递到会话Bean中的时候,就是这种状态,所以需要先通过merge操作转换成管理的状态,然后再持久化。

2.5合并分离的实体状态

merge操作可以完成合并操作。合并操作的语法如下:

u如果是新的实体,则会创建一个新的管理的实体;

u如果是被管理实体,则该操作被忽略;

u如果是删除的实体,则产生异常;

u如果是分离的实体,会创建一个新的管理的实体;

2.6管理的实体实例

可以通过contains方法来判断实体实例是否被管理。

3、实体生命周期回调方法

生命周期方法可以定义在

u实体类;

u超类;

u实体类所关联的实体监听器类;

u超类所关联的实体监听器类;

实体监听器类必须有一个无参数的构造方法。

可以通过元注释指定,也可以通过XML配置文件指定。

3.1生命周期回调方法的定义

定义在实体类或者超类的回调方法:

void ()

定义在实体监听器类的回调方法:

Void (Object o)

回调方法可以是任何访问控制类型,但是不能使用static和final修饰。

3.2生命周期回调方法使用的元注释

使用的元注释及含义如下:

uPrePersist,持久化之前产生该事件

uPostPersist,持久化之候产生该事件

uPreRemove,删除之前产生该事件

uPostRemove,删除之后产生该事件

uPreUpdate,更新之前产生该事件

uPostUpdate,更新之后产生该事件

uPostLoad,加载之后产生该事件

3.3实例

在第6讲的Ordertable实体类中增加如下7个生命周期回调方法:

@PostLoad

public void postLoad(){

System.out.println("PreLoad生命周期方法被调用!");

}

@PreRemove

public void preRemove(){

System.out.println("PreRemove生命周期方法被调用!");

}

@PrePersist

public void prePersist(){

System.out.println("PrePersist生命周期方法被调用!");

}

@PreUpdate

public void preUpdate(){

System.out.println("PreUpdate生命周期方法被调用!");

}

@PostPersist

public void postPersist(){

System.out.println("PostPersist生命周期方法被调用!");

}

@PostRemove

public void postRemove(){

System.out.println("PostRemove生命周期方法被调用!");

}

@PostUpdate

public void postUpdate(){

System.out.println("PostUpdate生命周期方法被调用!");

}

@Remove

public void remove(){

System.out.println("remove方法被调用!");

}

如果要持久化一个订单,会得到如下的输出结果:

PrePersist生命周期方法被调用!

PostPersist生命周期方法被调用!

如果要调用下面的代码:

Ordertable order = em.find(Ordertable.class,orderid);

Orderdetail item = new Orderdetail(orderid,goodsid);

em.persist(item);

item.setQuantity(quantity);

if(order.getOrderdetailCollection()==null)

order.setOrderdetailCllection(new Vector());

order.getOrderdetailCollection().add(item);

item.setOrdertable(order);

会得到如下的输出结果:

PreLoad生命周期方法被调用!

PreLoad生命周期方法被调用!

PreUpdate生命周期方法被调用!

PostUpdate生命周期方法被调用!

从运行结果看调用了两次PreLoad方法,这与持久性提供者有关。

如果执行下面的代码:

Ordertable order = em.find(Ordertable.class,orderid);

em.remove(order);

会得到如下的输出结果:

PreLoad生命周期方法被调用!

PreLoad生命周期方法被调用!

PreRemove生命周期方法被调用!

PostRemove生命周期方法被调用!

因为要先查找到实体才能删除,所以调用了PreLoad方法。

删除也可以使用下面的方法:

em.createQuery("delete from Ordertable o where o.orderid = ?1").setParameter(1,orderid).executeUpdate();

3.4一个生命周期事件的多个回调方法

同一个生命周期事件可以定义多个回调方法,可以在实体类、实体类的超类或者监听类上,如果定义了同一个生命周期事件的多个回调方法,则调用这些方法的顺序为:

如果有默认的监听器类,先调用默认的监听器类;

如果有实体监听器类,则先调用父层次的实体监听器类,后调用子层次的实体监听器类,如果在同一个实体类上定义了多个实体监听器类,按照定义的顺序执行;

如果父层次定义了生命周期回调方法,调用父层次的生命周期回调方法;

调用子层次的生命周期回调方法。

详细实例参考书上367页。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值