6.3 控制实体Bean的生命周期
与会话Bean类似,实体Bean也有自己的生命周期,分别对应不同的状态。下面我们首先来讲解实体Bean的状态和生命周期事件。
l 实体Bean的状态:新实体、持久化实体、分离实体、删除实体。
l 实体Bean的事件:@PostLoad、@PrePersist和@PostPersist、@PreUpdate和@PostUpdate、@PreRemove和@PostRemove。
然后讲解进行事件回调的两种方法。
l 外部回调:编写外部监听器。
l 内部回调:编写内部监听函数。
<DIV>
</DIV> |
6.3.1 实体Bean生命周期的4种状态
在上一节中我们讲解了使用实体管理器的各种函数操作数据库的方法,其中有两个方法与实体是否被容器管理有关:
l contains()用来检查实体是否被管理。
l clear()分离实体。
从以上的概念我们可以了解到,实体分为被容器管理和不被容器管理两种,这代表了实体的两种存在状态。
实际上,实体共有4种状态。
l new——新实体:实体由应用产生,和实体管理器没有任何联系,也没有唯一的标识符。
l managed——持久化实体:新实体和实体管理器产生关联(通过persist()、merge()等方法),在实体管理器中存在和被管理,标志是在实体管理器中有一个唯一的标识符。
l detached——分离的实体:实体有唯一的标识符,但它的标识符不被实体管理器管理。
l removed——删除的实体:实体被remove()方法删除,对应的记录将会在当前事务提交的时候从数据库中删除。
<DIV>
</DIV> |
6.3.2 实体Bean生命周期的回调事件
当你在执行各种持久化方法的时候,实体的状态会随之改变,状态的改变会引发不同的生命周期事件。这些事件可以使用不同的注释符来指示发生时的回调函数。
l @javax.persistence.PostLoad:加载后。
l @javax.persistence.PrePersist:持久化前。
l @javax.persistence.PostPersist:持久化后。
l @javax.persistence.PreUpdate:更新前。
l @javax.persistence.PostUpdate:更新后。
l @javax.persistence.PreRemove:删除前。
l @javax.persistence.PostRemove:删除后。
图6-3演示了回调事件和各种状态之间的转换关系。
以上的7种事件对应了数据库的4种操作。
1)数据库查询
@PostLoad事件在下列情况下触发:
l 执行EntityManager.find()或getreference()方法载入一个实体后。
l 执行JPQL查询后。
l EntityManager.refresh()方法被调用后。
2)数据库插入
@PrePersist和@PostPersist事件在实体对象插入到数据库的过程中发生:
l @PrePersist事件在调用persist()方法后立刻发生,此时的数据还没有真正插入进数据库。
l @PostPersist事件在数据已经插入进数据库后发生。
3)数据库更新
@PreUpdate和@PostUpdate事件的触发由更新实体引起:
l @PreUpdate事件在实体的状态同步到数据库之前触发,此时的数据还没有真正更新到数据库。
l @PostUpdate事件在实体的状态同步到数据库之后触发,同步在事务提交时发生。
4)数据库删除
@PreRemove和@PostRemove事件的触发由删除实体引起:
l @PreRemove事件在实体从数据库删除之前触发,即在调用remove()方法删除时发生,此时的数据还没有真正从数据库中删除。
l @PostRemove事件在实体从数据库中删除后触发。
<DIV>
</DIV> |
6.3.3 外部回调——编写外部监听器
对于以上7种事件类型,我们可以用两种方法来实现回调。
l 外部回调:即编写一个实体监听器,实现对某一个实体Bean的回调。
l 内部回调:通过在实体Bean内部的监听进行回调。
首先来看看外部回调的方法。
外部回调需要首先编写一个回调的监听器类,该类需要使用@javax.persistence.EntityListeners注释符绑定目标实体Bean,实现实体Bean的监听。
在该类中可以编写多个回调方法,通过在方法前添加不同的回调注释符实现事件的拦截。回调方法需要返回void型值,并且拥有一个Object参数,形式如下:
void method(Object obj);
下例定义了一个监听器类MyEntityListener.java,代码如下所示:
程序6-6 外部监听器类MyEntityListener.java
package com.ejb.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 MyEntityListener {
@PostLoad
public void postLoad(Object obj) {
System.out.println("载入了实体Bean:" + obj.getClass().getName());
}
@PrePersist
public void PreInsert(Object obj) {
System.out.println("持久化实体Bean前:" + obj.getClass().getName());
}
@PostPersist
public void postInsert(Object obj) {
System.out.println("持久化实体Bean后:" + obj.getClass().getName());
}
@PreUpdate
public void PreUpdate(Object obj) {
System.out.println("更新实体Bean前:" + obj.getClass().getName());
}
@PostUpdate
public void PostUpdate(Object obj) {
System.out.println("更新实体Bean后:" + obj.getClass().getName());
}
@PreRemove
public void PreRemove(Object obj) {
System.out.println("删除实体Bean前:" + obj.getClass().getName());
}
@PostRemove
public void PostRemove(Object obj) {
System.out.println("删除实体Bean后:" + obj.getClass().getName());
}
}
然后就可以在实体Bean类中通过@javax.persistence.EntityListeners注释来引用该监听器了,例如我们为Student.java类添加如下引用:
@EntityListeners({MyEntityListener.class})
public class Student implements Serializable {
...
}
现在重新发布EntityBeanTest.jar到JBoss服务器下,就会加载该监听器。此时再运行测试类StudentDAOClient.java,就会在JBoss控制台中输出如下信息:
14:07:39,843 INFO [STDOUT] 持久化实体Bean前:com.ejb.entitybean.Student
14:07:40,093 INFO [STDOUT] 持久化实体Bean后:com.ejb.entitybean.Student
这就表明,在执行数据插入前后分别回调了监听器PreInsert()和PostInsert()函数。
<DIV style="PADDING-BOTTOM: 0pt; PADDING-LEFT: 0pt; PADDING-RIGHT: 0pt; PADDING-TOP: 0pt" class=shape v:shape="_x0000_s1026">
提示 </DIV> |
这种通过编写外部监听器的方法,类似于AOP的功能,可以通过外部类实现对系统中目标类和函数的监听。关于AOP详细知识请参见作者的《开发者突击:精通AOP(AspectJ+ AspectWerkz+SpringAOP)》一书。
<DIV>
</DIV> |
6.3.4 内部回调——编写内部监听函数
除了外部类可以实现生命周期事件的回调外,你也可以把回调方法写在实体Bean中。要注意,直接写在实体Bean中的回调方法不需带任何参数,格式如下:
void method();
不同的回调函数也是通过回调注释符进行注释来标注的。如下例所示,我们为Student.java添加了回调函数:
程序6-7 内部监听演示Student.java
package com.ejb.entitybean;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import com.ejb.MyEntityListener;
@SuppressWarnings("serial")
@Entity
@Table(name = "Student")
@EntityListeners({MyEntityListener.class})
public class Student implements Serializable {
private Integer studentid; //学号
private String name; //姓名
private boolean sex; //性别
private Short age; //年龄
private Date birthday; //出生日期
private String address; //地址
private String telephone; //电话
...
package com.ejb.entitybean;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import com.ejb.MyEntityListener;
@SuppressWarnings("serial")
@Entity
@Table(name = "Student")
@EntityListeners({MyEntityListener.class})
public class Student implements Serializable {
private Integer studentid; //学号
private String name; //姓名
private boolean sex; //性别
private Short age; //年龄
private Date birthday; //出生日期
private String address; //地址
private String telephone; //电话
...
@PostLoad
public void postLoad(Object obj) {
System.out.println("载入了实体Bean:" + obj.getClass().getName());
}
@PrePersist
public void PreInsert(Object obj) {
System.out.println("持久化实体Bean前:" + obj.getClass().getName());
}
@PostPersist
public void postInsert(Object obj) {
System.out.println("持久化实体Bean后:" + obj.getClass().getName());
}
@PreUpdate
public void PreUpdate(Object obj) {
System.out.println("更新实体Bean前:" + obj.getClass().getName());
}
@PostUpdate
public void PostUpdate(Object obj) {
System.out.println("更新实体Bean后:" + obj.getClass().getName());
}
@PreRemove
public void PreRemove(Object obj) {
System.out.println("删除实体Bean前:" + obj.getClass().getName());
}
@PostRemove
public void PostRemove(Object obj) {
System.out.println("删除实体Bean后:" + obj.getClass().getName());
}
}
此时发布代码并执行客户端测试,也会输出同样的回调信息。
相关推荐
* 第6课:实体Bean(Entity Bean)——Java持久化JPA + 第一个实体Bean实例——建立与数据库的连接 + 实例管理器EntityManager——执行数据库更新 + 控制实体Bean的生命周期 * 第7课:实体关系映射(ORM) + 单...
3. **查询语言(JPA QL)**:除了基本的CRUD操作,还可以使用JPA的查询语言(JPQL)执行更复杂的SQL查询,如`SELECT e FROM EntityBean e WHERE e.property = :value`。 ### 四、EJB实体Bean的生命周期管理 EJB...
3. **开发实体Bean**:实体Bean需要实现特定的接口,如`javax.ejb.EntityBean`或使用注解`@Entity`(在Java EE 5及以后版本)。这些Bean通常使用JPA(Java Persistence API)进行持久化操作,通过ORM(对象关系映射...
在 JPA 出现之前,Java EE 应用程序通常使用容器管理的实体 Bean 来处理数据持久化。这种模型虽然有效,但配置繁琐且不够灵活。JPA 的引入极大地简化了这一过程。 使用 JPA,开发人员可以将任何普通的旧式 Java ...
3. **Entity Beans 3.0(EJB 3.0引入)**:简化了Entity Bean的使用,采用了注解(Annotations)方式,使得持久化过程更为简洁,与JPA(Java Persistence API)紧密集成。 **EJB的生命周期** 无论是Session Bean...
1. **生命周期**:实体Bean有三种生命周期状态:瞬时(Transient)、持久化(Persistent)和脱管(Detached)。瞬时Bean未与容器关联,不具有持久性;持久化Bean已由容器管理,并存储在数据库中;脱管Bean是从持久化...
在EJB中,实体Bean可以被声明为`@Entity`,并使用JPA(Java Persistence API)或Hibernate等ORM(对象关系映射)框架来管理其生命周期和数据持久化。 **BMP(Business Managed Persistence)**: 在BMP模式下,...
### JPA实体Bean配置与增删改操作详解 ...以上介绍了JPA的基本概念、环境搭建流程、持久化文件配置以及实体Bean定义的关键知识点。通过这些知识点的学习,开发者可以更好地理解和使用JPA进行数据库操作。
- **容器管理的持久性 (Container-Managed Persistence, CMP)**: EJB 3.0引入了注解,使得实体Bean的持久化更加简单,开发者无需编写XML配置文件,只需在Bean类上使用`@Entity`注解即可。 - **Java Persistence ...
JPA是Java持久化API的标准规范,提供了一个通用的API来访问、管理和持久化数据。JPA支持多种持久化机制,包括关系数据库、对象数据库和XML数据库等。JPA的主要特点是提供了一个通用的API来访问和管理数据,使得开发...
- **Entity Bean**:用于表示数据库中的持久化对象,实现业务实体的数据管理和业务逻辑。传统的Entity Bean(CMP)由容器管理持久性,而现代的JPA(Java Persistence API)通常与Entity Bean一起使用,提供更灵活的...
实体Bean继承是Java企业级应用开发中的一个重要概念,特别是在使用Java持久化技术(JPA)进行数据存储时。实体Bean代表数据库中的一个表,而实体Bean之间的继承关系则需要在数据库层面进行适当的映射,以便正确地...
在Java源代码中,我们可以定义一个实体Bean类,使用`@Entity`注解标记,表明这是一个持久化类。同时,通过`@Table`注解指定与之关联的数据库表名。 对于实体Bean中的属性,可以使用`@Id`注解声明主键,通常配合`@...
Java Persistence API(JPA)是Java平台上的一个标准,用于管理和持久化对象。它简化了在关系数据库中存储和检索Java对象的过程,是JAVA EE5中引入的重要组件。JPA通过提供ORM(对象关系映射)能力,使得开发人员...
其中,会话bean用于处理业务逻辑,实体bean用于表示数据库中的持久化对象,而消息驱动bean则处理JMS(Java Message Service)消息。 JPA是Java平台上的一个规范,它的主要目标是简化Java应用程序的持久化层开发。...
在JPA环境中,配置文件通常是`persistence.xml`,它定义了持久化单元(`persistence-unit`)。在这个配置文件中,你可以设置数据库连接参数,比如`hibernate.dialect`定义数据库方言,`hibernate.hbm2ddl.auto`控制...
本文将深入探讨EJB3中的Entity Bean,它是EJB3中的持久化组件,用于代表数据库中的实体。 1. **实体Bean的概念** 实体Bean是EJB3中的数据存储模型,它与数据库中的记录相对应。在EJB3中,实体Bean不再需要编写...
2. EntityBean类:带有@Entity注解的Java类,对应数据库表的实体。 3. 数据源配置文件:如context.xml或application.xml,定义JNDI数据源。 4. persistence.xml:JPA的配置文件,用于指定实体类、数据源等信息。 5. ...
Java持久化技术的发展可以分为四个阶段: JDBC、关系对象映射(Object Relational Mapping,ORM)、Java数据对象(Java Data Object,JDO)和Java Persistence API(JPA)。 1.1 JDBC JDBC(Java Database ...
3. **实体管理器(Entity Manager)**:用于管理实体对象的生命周期,执行持久化操作的核心组件。 4. **持久单元(Persistence Unit)**:是JPA中用于配置和管理实体管理器的最小单位。 #### 三、搭建JPA环境 为了更好...