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 class="native" />
           </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
                       class="hibernate.entityObject.onetomany.foreignKeyAssociations.Address" />

           </bag>
           </class>
    </hibernate-mapping>

 

    <hibernate-mapping>
         <class
         name="hibernate.entityObject.one_to_many.foreignKeyAssociations.Address"
         table="Address">
              <id name="addressId " type="long">
                    <generator class="native" />
              </id>
              <property name="street" type="string" />
              <property name="zipcode" type="string" />
              <property name="city" type="string" />
         </class>
    </hibernate-mapping>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值