实体是一个可持久化的域对象。程序出来产物就是实体类,实体类可以作为一个辅助类,如可作为一个实体类的助手类或者作为代表实体类的状态的类。 实体类的要求
·实体类必须用entity标识符来声明,或者在配制文件中指明某个类为实体类。
·实体类必须有一个无参数的构造器。它也可以有其他的构造器。这个无参数的构造器必须是public或protected的。
·如果实体实例作为一个分离对象按值传递(如通过一个远程接口),则实体类必须实现serializable接口。
·实体类不允许是final的,它的所有方法都不允许是final的。
·实体支持继承,多义关联,多义查询。实体类可以是抽象的,也可以是具体的。实体类可以继承非实体类,非实体类也可以继承实体类。
·实体的状态由它的变量代表,这是和JavaBean的属性一样的。实体方法可以直接获得变量,但是实体的客户端必须通过获取变量的方法(getter/setter)来获取变量。实例变量必须是private,protected或包内可见的。
1、持久化字段和属性
实体的状态可以通过它的setter/getter方法或实例变量获得,这两种方式通称为运行时持久化提供器(指持久化实现的运行环境,在EJB环境中,可能是EJB容器,也可能是第三方提供的集成在EJB容器内的持久化实现):
·如果声明实体的标识符的元素值为access=FIELD,那么运行时持久化提供器直接获取实例变量,并且持久化所有non-transient实例变量(没有用Transient标识符标识的变量)。
·如果声明实体的标识符的元素值为access=PROPERTY,或者没有指定access的值,那么运行时持久化提供器通过getter/setter方法获取实例变量,并且持久化所有non-transient实例变量(没有用Transient标识符标识的变量)。所有的属性获取方法必须是public或protected。
·当使用FIELD类型时,O/R影射标识符用在变量上。当用PROPERTY时,O/R影射标识符用在getter/setter方法上。(注意:当在加载或存储持久化状态时,持久化提供者按照什么样的顺序来调用这些方法是不确定的。因此包含在这些方法内的业务逻辑不能依赖指定的调用顺序)。
当使用持久化属性时,要求实体遵循JavaBean的方法约定。在这种情况下,实体的类型T的每一个持久化属性property,都有一个getter方法getProperty和一个setter方法setProperty,对于boolean值则为isProperty。
对于简单值得持久化属性,这些方法如下形式:
对于集合类型的字段和属性,则必须用java.util.Collection接口定义,不管实体类是否遵循JavaBean的规范。下面的接口都是可以的:java.util.Collection,java.util.List,java.util.Set,java.util.Map。
对于集合类型的字段和属性,类型T必须是上述集合类型中的一个。也可以使用这些集合类型的泛型变量(如:Set<order>)。</order>
为了返回和设置实例的持久化状态,实例的属性获取方法内可以包含别的业务逻辑,如执行验证。注意:当属性的获取类型为PROPERTY时,持久化运行环境才会执行这些业务逻辑。但在增加的业务逻辑中应该有警告信息。
在属性获取方法内抛出的运行时异常会引起事务回滚。当持久化运行时环境使用这些属性获取方法加载或存储实例状态时,如果抛出应用异常,则会引起持久化运行环境回滚事务,并且会抛出封装了应用异常的PersitenceException。
实体的子类可以覆盖它的属性获取方法。然而,兼容性好的应用不需要覆盖应用在父类持久化字段和属性上的O/R影射元数据。
实体类的持久化字段和属性可以是原始类型、java.lang.String、也可以是其他可序列化类型(包括原始类型的封装类型,java.math.BigInteger,java.math.BigDecimal,java.util.Date,java.util.Calendar,java.sql.Date,java.sql.Time,java.sql.Timestamp,用户自定义类型,byte[],Byte[],char[]和Character[])、enum、实体类型和/或实体类型的集合、以及嵌套类型。
O/R影射元数据可以用来客户化O/R影射、实体状态和实体间关系的加载和存储。
2、创建实体实例
通过new操作符创建实体实例。当第一次创建实体实例时,这个实例是非持久化的。通过EntityManager的API可以将实例持久化。实体实例的生命周期在以后的文章中描述,在这里我就不再详细讲述了。
3、主键和实体唯一标识
每一个实体必须有一个主键。一个简单主键(非组合主键)必须对应于实体类的一个单一持久化字段或属性。一个组合主键必须对应于一个单一持久化字段或属性,或者对应于一组持久化字段或属性。即必须定义一个主键类来代表组合主键。组合主键通常在这种情况下发生:当从映射逻辑数据库时,但数据库的主键是由几列组合而成的。
主键(字段或组合主键的属性)的类型必须是:任何原始类型、任何原始类型的封装类型、java.lang.String、java.util.Date、java.sql.Date。然而,通常情况下,复杂的数字类型(如float类型)不要用作主键。
实体类的字段和属性都可以被主键类获取。
组合主键需遵循以下规则:
·主键类必须是public的,并且有一个public的无参数构造器。
·若access=PROPERTY,则主键类的属性必须是public的或protected的。
·主键类必须是可序列化的。
·主键类必须定义equals和hashCode方法。这些方法的值相等的语义必须和数据库中字段相等的语义一致。
·组合主键可以是实体类的可嵌入类,也可以是实体类的多个字段或属性。
·如果符合主键类对应于实体类的多个字段或属性,那么主键类的字段或属性的名称必须和实体类的相应字段或属性的名称和类型一致。但是允许主键类和实体类采用不同的获取类型(PROPERTY或FIELD)。
·应用程序不能够改变主键的值。规范中不定以发生改变时的处理方式,具体的实现可以但不要求抛出一个异常。
4、可嵌入类
实体类可以用其他类来代表实体类的状态。这些类没有可持久化的唯一标识。相反,他们仅仅作为实体类实例的内部对象。这些对象绝对是属于他们的属主实体类,而不会被其他实体类共享。共享这些可嵌入类会造成语义混淆,因为这些对象没有唯一标识符,他们和实体类实例一起才能构成完整的数据库映射。(在以后的版本中可能会支持嵌入类的集合、多义和继承操作。)
可嵌入类必须遵循1.1的实体类规范,但不同的是,它不必使用Entity声明。
5、映射非关系字段或属性的缺省值
如果一个可持久化字段或属性(非关系字段)没有用第8章定义的标识符标识的话,则需要按顺序执行下面的规则:
·如果是一个类,而且这个类用@Embeddable标识。则被映射为@Embeddable。
·如果字段或属性的类型是下面类型中的任意一个时,则被映射为@Basic。类型有:原始类型、原始类型的封装类型、java.lang.String、java.math.BigInteger、java.math.BigDecimal、java.util.Date、java.util.Calendar、java.sql.Date、java.sql.Time、java.sql.Timestamp、byte[]、Byte[]、char[]、Character[]、enums、以及任何实现了序列化接口的类型。
如果没有使用标识符,而且也没有应用上述规则的话,就是错误的。
6、实体关系
实体间的关系可以是一对一、一对多、多对一、多对多的。
如果在两个实体间有关系,则在持久化属性或引用实体的实例变量上必须指定关系标识符。关系标识符有:OneToOne、OneToMany、ManyToOne、ManyToMany。由于关系没有指定目标类型(如,java的泛型类型没有应用到集合类上),所以必须指定关系目标的实体。
这些标识符反映了在关系数据库模型中的实际情况。使用关系模型标识符使得与关系数据库相关的O/R映射完全缺省,更加易于配置。这在1.1.8章节中详细描述。
关系可以是双向的或单向的。双向关系既有所有方也有被属方。单向关系只有所有边。所有边决定了数据库中的更新。详见2.2.3。
下面的规则应用于双向关系:
·双向关系的反向边必须用OneToOne、OneToMany或ManyToMany的mappedBy元素指向它的所有边。mappedBy元素指明了实体的哪一个字段或属性是关系的拥有者。
·如果access=PROPERTY,那么主键类的属性必须是public或protected的。
·主键类必须是可序列化的。
·主键类必须定义equals和hashCode方法。相等的语义必须和主键映射到数据库中的数据库类型相等的语义一致。(即如果两个对象的主键类相等,则它们在数据库中就是同一条记录)
·组合主键可以映射到一个嵌套类,也可以映射到实体类的多个字段。
·如果组合主键类被映射到实体类的多个字段或属性,那么主键类的这些字段或属性的名字和类型必须和实体类是一样的。但是,对实体类和主键类可以使用不同的属性获取类型(PROPERTY或FILED)。
·应用不能改变主键的值。可以实现成能改变,但不要求。如果没有实现,但是去修改主键的值时,可以抛出异常。
7、可嵌入类
实体可以使用其他的类来作为实体状态,这些类没有持久化标识。他们只是作为实体的嵌入对象。这些嵌入对象只属于他们的所属的实体,不能被其他的持久化实体共享。没有规定如果共享这些对象会如何。因为这些对象没有持久化标识,所以它们通常和实体实例一起映射到数据库中。(在这个规范的未来版本会要求支持嵌入类的集合操作,以及多态和集成)。
嵌入类除了不用Entity注解声明为实体外,必须遵守在1.1章节中对实体的所有要求。
8、映射非关系型字段或属性的缺省规则
如果一个持久化字段或属性不是关系型属性,即它不能用在第9章中定义的映射注解标注(或者同样的映射信息不能在XML中描述),那么将按顺序使用以下缺省的映射规则:
·如果一个类用@Embeddable标识,则它被映射为@Embedded。
·如果字段或属性的类型属于以下类型中的一个时,则被映射为@Basic。这些类型是:Java的原始类型,原始类型的封装类型,java.lang.String,java.math.BigInteger,java.math.BigDecimal,java.util.Date,java.util.Calendar,java.sql.Date,java.sql.Time,java.sql.Timestamp,byte[],Byte[],char[],Character[],enums,以及任何其他实现了序列化接口的类型。
如果没有用注解标注和应用以上规则,则都是错误的
相关推荐
|-- META-INF |--persistence.xml EJB3的持久化配置文件 <br> |--DBScript |--employee.sql 数据库脚本及测试数据 |--mysql-connector-java-5.1.5-bin.jar MySql的驱动程序包 |--mysql-ds....
6.5 持久化实体管理器ENTITYMANAGER..43 6.5.1 Entity获取find()....43 6.5.2 添加 persist().........43 6.5.3 更新 Merge() .........44 6.5.4 删除 Remove() .......44 6.5.5 执行 EJB3 QL操作createQuery() 44 ...
实际上这表达了和Hibernate持久化实体对象同样的概念. 它们的映射都通过JDK5.0注解来定义(EJB3规范已经定义了对应的XML描述语法). 注解分为两个部分,分别是逻辑映射注解和物理映射注解, 通过逻辑映射注解可以描述...
3.2.3 编写POJO和持久化实体类 3.2.4 实现POJO关联 3.2.5 把逻辑添加到访问方法 3.3 ORM元数据 3.3.1 XML中的元数据 3.3.2 基于注解的元数据 3.3.3 使用XDoclet 3.3.4 处理全局的元...
2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 实体域对象的其他持久化模式 2.3.1 主动域对象模式 ...
10.3.2 实体类的要求 382 10.3.3 实体的状态 383 10.3.4 管理实体的方法 384 10.4 实体的基本映射387 10.4.1 映射实体类的属性 387 10.4.2 将实体映射到多个表 394 10.4.3 映射复合类型的属性 396 10.4.4 映射实体类...
2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 实体域对象的其他持久化模式 2.3.1 主动域对象模式 ...
2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 实体域对象的其他持久化模式 2.3.1 主动域对象模式 ...
2.1 直接通过JDBC API来持久化实体域对象 2.2 ORM简介 2.2.1 对象-关系映射的概念 2.2.2 ORM中间件的基本使用方法 2.2.3 常用的ORM中间件 2.3 实体域对象的其他持久化模式 2.3.1 主动域对象模式 ...
实际上表达了和Hibernate持久化实体对象同样的概念。他们的映射都通过JDK5.0注释来定义(EJB3规范中的XML描述语法至今还没有定下来)。注释分为两个部分,分别是逻辑映射注释和物理映射注释,通过逻辑映射注释可用描述...
294 16.3.5 数据库连接池中使用JDBC 297 16.4 小结 302 第17章 ORM与Java持久化机制 303 17.1 ORM概述 303 17.2 域模型 304 17.3 实体域对象的持久化模式 304 17.4 JPA 305 17.4.1 实体 306 17.4.2 EntityManager ...
load方法可返回实体的代理类实例,而get方法永远直接返回实体类。load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找。 八、Action接受用户参数输入 Action接受用户...
J2EE通信 通信概述 JMS的详细情况 消息驱动EJB 小结 第24章 Java数据对象(JDO) 概述 JDO对象模型 JDO API JDO实例的生命周期 JDO和EJB 开发可持久类 范例应用程序 配置FFJ...
Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,...
Java Bean 是可复用的组件,对Java Bean并没有严格的规范,理论上讲,任何一个Java类都可以是一个Bean。但通常情况下,由于Java Bean是被容器所创建(如Tomcat)的,所以Java Bean应具有一个无参的构造器,另外,...
答:JDO是java对象持久化的新的规范,为java data object的简称,也是一个用于存取某种数据仓库中的对象的标准化API。 CORBA? 答:CORBA标准是公共对象请求代理结构,用途为:用不同的程序设计语言书写,在不同的...
用cascading实现传播性持久化(Transitive persistence) 2.2.5.5. 关联关系获取 2.2.6. 映射复合主键与外键 2.2.7. 映射二级表(secondary tables) 2.3. 映射查询 2.3.1. 映射EJBQL/HQL查询 2.3.2. 映射本地化...
实体Bean类(SavingsAccountBean) 69 EntityBean接口 69 ejbCreate方法 70 EjbPostCreate方法 71 ejbRemove方法 72 ejbLoad和ejbStore方法 72 查找方法(Finder) 73 商业方法 74 Home方法 76 数据库访问 77 Home...
9.2.6 使用反向工程生成持久化对象、映射文件和DAO类 143 9.2.7 使用Hibernate功能 151 9.3 MyEclipse中Hibernate框架的高级操作 152 9.3.1 在Hibernate反向工程中定制映射关系 153 9.3.2 使用HQL编辑器 154 9.4 ...