Hibernate常见误区——正确区分值对象和实体对象
声明:该部分内容参考http://blog.csdn.net/gudong2945/article/details/7050196
?
????? 值对象和实体对象是Hibernate的重要概念,当然在jpa中也有相应的概念,他们在语义上是相同的。常常听
到人们抱怨Hibernate中对象之间的映射关系配置很难,而且经常出现一些莫名奇妙的问题。其真正原因是没有
正确的区分值对象和实体对象而进行了错误的设计(其实很多时候就没有值对象的概念,而在系统中将所有的对
象都归结为了实体)。
1. 什么是值对象?
??? 举个例子:如果你又User类和Address类,对于每个具体的User有对应的Address,当然这个Address可以
是多个(家庭地址、公司地址)等等。而这些地址只能依赖于User类而存在,并且不存在其他对象对某个具体
Address的引用(此处忽略两个人有同一地址的情况)。这时候Address就是一个值对象。更抽象的,对于一个
实体如何区分是值对象和实体对象主要从以下三点考虑
??? (1) 是否有一个依赖的生命周期,如果此对象依赖于另一个对象的声明周期,就认为他是有一个依赖的生命周
??? 期的;
??? (2) 是否需要它们自己的同一性(java中体现为 ==? 和 equals() 方法,数据库中体现为主键是否相等),就
??? 是说你的代码中会不会去比较两个对象是否具有同一性,在上例中体现为我们永远不会去比较两个地址是否相
??? 等(== 或者 equlas());
??? (3) 是否需要支持共享引用:如果一个对象有一个依赖的生命周期,不需要它们自己的同一性,并且不必支持
??? 共享引用的话它就是个值类型的对象。
??? 例如:报销单下有报销明细,报销明细就是一个值对象,再如一个商品有它的多张照片,照片就是值对象,更
??? 一般的java中的String,Integer,Double.....都是值对象
2. 为什么要使用值对象?
??? Hibernate对值对象的的映射提供了特别的支持,如果你有一个一对多的关联,而且你希望在一的一方控制一
??? 切的话,更多情况下多的一方是一个值对象。如果是值对象你可以避免考虑级联更新的问题,孤儿删除的问题
??? 等等,因为Hibernate已经处理了这些问题。
?
??? 常见值对象集合的映射如下:(以商品和图片(路径)为例)
??? (1) set:
??? <set name="images" table="ITEM_IMAGE">
????????? <key column="Item_id"/>
????????? <element type="string" column="filename" not-null="true"/>
??? </set>
??? (2) list
??? <list name="images" table="ITEM_IMAGE">
????????? <key column="Item_id"/>
????????? <list-index column="prosition"/>
????????? <element type="string" column="filename" not-null="true"/>
??? </set>
??? (3) map
??? <map name="images" table="ITEM_IMAGE">
????????? <key column="Item_id"/>
????????? <map-index column="imagename" type="stirng"/>
????????? <element type="string" column="filename" not-null="true"/>
??? </map>
??? 值对象级联删除示例:(以User和Address为例)
??? (1) 实体:
??? public class User {
???????????? private long userId;
???????????? private String firstname;
???????????? private String lastname;
???????????? private Collection<Address> addresses = new ArrayList<Address>();
???????????? /* 省略Get和Set方法*/
???????????? ...
??? }
??? public class Address {
???????????? private long addressId;
? ? ? ?????? private String street;
???????????? private String zipcode;
???????????? private String city;
???????????? /* 省略Get和Set方法*/
???????????? ...
??? }
??? (2) XML:
??? <hibernate-mapping>
?????????? <class name="hibernate.entityObject.one_to_many.foreignKeyAssociations.User"
??? ?????? table="USER">
??? ?????? <id name="userId" type="long">
??? ??? ???????? <column name="USER_ID" />
??? ??? ???????? <generator />
??? ?????? </id>
??? ?????? <property name="firstname" type="string">
??? ??? ???????? <column name="FIRSTNAME" length="40" />
??? ?????? </property>
??? ?????? <property name="lastname" type="string">
??? ??? ???????? <column name="LASTNAME" length="50" />
??? ?????? </property>
??? ?????? <bag name="addresses" cascade="all-delete-orphan" lazy="false">
??? ??? ???????? <key column="USER_ID"></key>
??? ??? ???????? <one-to-many
??? ??? ??? ?????????? />
??? ?????? </bag>
?????????? </class>
??? </hibernate-mapping>
?
??? <hibernate-mapping>
???????? <class
??? ???? name="hibernate.entityObject.one_to_many.foreignKeyAssociations.Address"
??? ???? table="Address">
??? ????????? <id name="addressId" type="long">
??? ??? ??????????? <generator />
??? ????????? </id>
??? ????????? <property name="street" type="string" />
??? ????????? <property name="zipcode" type="string" />
??? ????????? <property name="city" type="string" />
???????? </class>
??? </hibernate-mapping>
?