博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EJB---->Entity 的生命周期和状态、回调函数
阅读量:5865 次
发布时间:2019-06-19

本文共 6650 字,大约阅读时间需要 22 分钟。

一、四种Entity 的状态:
1. 新实体(new)。Entity 由应用产生,和EJB3 Persistence 运行环境没有联系,也没有唯一的标示符(Identity)。
2. 持久化实体(managed)。新实体和EJB3 Persistence 运行环境产生关联(通过persist(), merge()等方法),在EJB3
Persistence 运行环境中存在和被管理,标志是在EJB3 Persistence 运行环境中有一个唯一的标示(Identity)。
3. 分离的实体(detached)。Entity 有唯一标示符,但它的标示符不被EJB3 Persistence 运行环境管理, 同样的该
Entity 也不被EJB3 Persistence 运行环境管理。
4. 删除的实体(removed)。Entity 被remove()方法删除,对应的纪录将会在当前事务提交的时候从数据库中删除。
当你执行持久化方法,如: persist( ), merge( ), remove( ), find( )或JPQL 查询的时候,实体的生命周期事件将会触发。
例如,persist( )方法触发数据插入事件,merge( )方法触发数据更新事件,remove( )方法触发数据删除事件,通过JPQL 查询实体会触发数据载入事件。有时实体类得到这些事件发生的通知是非常有用的,例如,你想创建一个日志文件,用来记录数据库每条记录发生的操作(如:添,删,载入等)持久化规范允许你在实体类中实现回调方法,当这些事件发生时将会通知你的实体对象。当然你也可以使用一个外部类去拦截这些事件,这个外部类称作实体监听者。通过@EntityListeners 注释绑定到实体Bean
 
如何在实体类中实现生命周期回调方法及怎样实现一个能拦截实体生命周期事件的实体监听者?
二、生命周期回调事件
如果需要在生命周期事件期间执行自定义逻辑,请使用以下生命周期事件注释关联生命周期事件与回调方法,EJB 3.0 允许你将任何方法指定为回调方法。这些方法将会被容器在实体生命周期的不同阶段调用。
@PostLoad 事件在下列情况触发
1.执行EntityManager.find( )或getreference( )方法载入一个实体后
2.执行JPQL 查询过后
3.EntityManager.refresh( )方法被调用后
@PrePersist 和@PostPersist 事件在实体对象插入到数据库的过程中发生,@PrePersist 事件在调用EntityManager.persist( )方法后立刻发生,级联保存也会发生此事件,此时的数据还没有真实插入进数据库。@PostPersist 事件在数据已经插入进数据库后发生。
@PreUpdate 和@PostUpdate 事件的触发由更新实体引起,@PreUpdate 事件在实体的状态同步到数据库之前触发,此时的数据还没有真实更新到数据库。@PostUpdate 事件在实体的状态同步到数据库后触发,同步在事务提交时发生。
@PreRemove 和@PostRemove 事件的触发由删除实体引起,@PreRemove 事件在实体从数据库删除之前触发,
即调用了EntityManager.remove()方法或者级联删除时发生,此时的数据还没有真实从数据库中删除。@PostRemove 事件在实体已经从数据库中删除后触发。
三、在外部类中实现回调
Entity listeners(实体监听者)用作拦截实体回调事件,通过@javax.persistence.EntityListeners 注释可以把他们绑
定到一个实体类。在Entity listeners 类里,你可以指定一个方法拦截实体的某个事件,所指定的方法必须带有一个Object 参数及返回值为void,格式如下:
void <MethodName>(Object)
通过为方法加上事件注释,即完成特定事件与回调方法的关联。
EntityListenerLogger.java
package com.foshanshop.ejb3.bean.listener;import javax.persistence.PostLoad;import javax.persistence.PostPersist;import javax.persistence.PostRemove;import javax.persistence.PostUpdate;import javax.persistence.PrePersist;import javax.persistence.PreRemove;import javax.persistence.PreUpdate;public class EntityListenerLogger {@PostLoadpublic void postLoad(Object entity) {System.out.println("载入了实体Bean{" + entity.getClass().getName( ) + "}");}@PrePersistpublic void PreInsert(Object entity) {System.out.println("对实体Bean{" + entity.getClass().getName( )+ "}调用了EntityManager.persist()或级联保存");}@PostPersistpublic void postInsert(Object entity) {System.out.println("在JDBC API层对实体Bean{" + entity.getClass().getName( )+ "}执行了插入操作,但事务还未提交");}@PreUpdatepublic void PreUpdate(Object entity) {System.out.println("对实体Bean{" + entity.getClass().getName( )+ "}调用了EntityManager.merge()或级联更新");}@PostUpdatepublic void PostUpdate(Object entity) {System.out.println("在JDBC API层对实体Bean{" + entity.getClass().getName( )+ "}执行了更新操作,但事务还未提交");}@PreRemovepublic void PreRemove(Object entity) {System.out.println("对实体Bean{" + entity.getClass().getName( )+ "}调用了EntityManager.remove()或级联删除");}@PostRemovepublic void PostRemove(Object entity) {System.out.println("实体Bean{" + entity.getClass().getName( )+ "}已经从数据库中删除");}}

我们使用@javax.persistence.EntityListeners 注释把上面的实体监听类绑定到下面的实体中

@javax.persistence.EntityListeners 注释可以绑定多个实体监听类,之间用逗号分隔,监听的顺序按照定义的先后顺序执行。

EntityLifecycle.java
package com.foshanshop.ejb3.bean;import java.io.Serializable;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.EntityListeners;import javax.persistence.GeneratedValue;import javax.persistence.Id;import com.foshanshop.ejb3.bean.listener.EntityListenerLogger;@Entity@EntityListeners({EntityListenerLogger.class})public class EntityLifecycle implements Serializable{    private static final long serialVersionUID = 2619167645480125649L;    private Integer id;    private String name;       public EntityLifecycle() {}        public EntityLifecycle(String name) {        this.name = name;    }    @Id    @GeneratedValue      public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    @Column(nullable=false,length=32)    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    }
EntityLifecycleDAOBean.java
package com.foshanshop.ejb3.impl;import java.util.List;import javax.ejb.Remote;import javax.ejb.Stateless;import javax.persistence.EntityManager;import javax.persistence.PersistenceContext;import javax.persistence.Query;import com.foshanshop.ejb3.EntityLifecycleDAO;import com.foshanshop.ejb3.bean.EntityLifecycle;@Stateless@Remote (EntityLifecycleDAO.class)@SuppressWarnings("unchecked")public class EntityLifecycleDAOBean implements EntityLifecycleDAO {    @PersistenceContext protected EntityManager em;        public EntityLifecycle Load() {        return em.find(EntityLifecycle.class, 1);//此处将会触发@PostLoad事件          }    public void Persist() {        EntityLifecycle entitylifecycle = new EntityLifecycle("孙丽");        em.persist(entitylifecycle);    }public void Remove() {        Query query = em.createQuery("select e from EntityLifecycle e");        List
result = (List
)query.getResultList(); if (result.size()>0){ EntityLifecycle entitylifecycle = result.get(0); em.remove(entitylifecycle); } } public void Update() { Query query = em.createQuery("select e from EntityLifecycle e"); List
result = (List
)query.getResultList(); if (result.size()>0){ EntityLifecycle entitylifecycle = result.get(0); entitylifecycle.setName("张权"); } }}
四、在Entity 类中实现回调
除了外部类可以实现生命周期事件的回调,你也可以把回调方法写在Entity 类中。要注意:直接写在Entity 类
中的回调方法不需带任何参数.
@Entity@Table(name = "EntityLifecycle")public class EntityLifecycle implements Serializable{@PostLoadpublic void postLoad() {System.out.println("载入了实体Bean{" + this.getClass().getName( ) + "}");}@PrePersistpublic void PreInsert() {System.out.println("对实体Bean{" + this.getClass().getName( )+ "}调用了EntityManager.persist()或级联保存");}@PostPersistpublic void postInsert() {System.out.println("在JDBC API层对实体Bean{" + this.getClass().getName( )+ "}执行了插入操作,但事务还未提交");}@PreUpdateJboss EJB3.0 实例教程传智播客(www.itcast.cn)软件培训参考教材版权所有:黎活明public void PreUpdate() {System.out.println("对实体Bean{" + this.getClass().getName( )+ "}调用了EntityManager.merge()或级联更新");}@PostUpdatepublic void PostUpdate() {System.out.println("在JDBC API层对实体Bean{" + this.getClass().getName( )+ "}执行了更新操作,但事务还未提交");}@PreRemovepublic void PreRemove() {System.out.println("对实体Bean{" + this.getClass().getName( )+ "}调用了EntityManager.remove()或级联删除");}@PostRemovepublic void PostRemove() {System.out.println("实体Bean{" + this.getClass().getName( )+ "}已经从数据库中删除");}}

 

转载地址:http://obynx.baihongyu.com/

你可能感兴趣的文章
Linux编译+更换3.4版本内核教程
查看>>
新人上手第一步 for 菜鸟
查看>>
centos7安装apache
查看>>
数据库启动报错 ORA-01078和LRM-00109
查看>>
选项卡面板代码
查看>>
pycharm pyspark 配置
查看>>
mysql主从复制
查看>>
linux uvc深入理解(二)
查看>>
第六课_质量管理、人力资源管理
查看>>
關於如何使用python +django+mongoengine 的學習
查看>>
运营心得、JVM配置、tomcat配置、
查看>>
关联数组与索引数组
查看>>
锁-Memcached 和 Redis 分布式锁方案
查看>>
urllib记录
查看>>
我所理解的“长连接”
查看>>
webpack4配置详解之常用插件分享
查看>>
java利用ftpClient来创建多层目录文件
查看>>
运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)
查看>>
IT运维工作的“三境界”
查看>>
安装Ubuntu虚拟系统
查看>>