chho的专栏

对于整个世界我微不足道,但是我对于自己确是全部

常浩ID:chho
75135次访问,排名1299好友0人,关注者1
chho的文章
原创 106 篇
翻译 0 篇
转载 0 篇
评论 24 篇
chho的公告


名字:Chho
JAVA程序员,现在对Linux产生了浓厚的兴趣。

我的Mail:
最近评论
文章分类
收藏
    相册
    存档
    软件项目交易
    订阅我的博客
    XML聚合  FeedSky
    订阅到鲜果
    订阅到Google
    订阅到抓虾
    订阅到BlogLines
    订阅到Yahoo
    订阅到GouGou
    订阅到飞鸽
    订阅到Rojo
    订阅到newsgator
    订阅到netvibes

    原创 Hibernate入门20 - cascade持久化收藏

    新一篇: Hibernate入门21 - 双向关联与inverse设定 | 旧一篇: Hibernate入门19 - 一对多实体映像

    入门 20 - cascade持久化

     在Java程序中,对象与对象之间会透过某些关系互相参考,如果有一个对象已经是持久化对象,被它参考的对象直觉上也应该要持久化,以维持对象之间关联的完整性,这是藉由可达性完成持久化(Persistence by reachability)的基本概念。
     如果将对象之间的关联想象为一个树形图,从某一个持久化物件为树根出发,父节点若是持久化对象,则被父节点参考到的子节点应自动持久化,而另一方面,如果有一子节点没办法藉由任何的父节点来参考至它,则它没有被持久化的需求,它应从数据库中加以删除。
     Hibernate并没有完全实现以上的概念,它让使用者自行决定自动持久化的方式,当对象之间被指定关联(例如多对一、一对多等),您可以决定被持久化对象关联的暂存对象是否进行自动持久化与如何自动持久化。
     以之前「多对一实体映像」主题为例,之前我们在设定好User类别中的Room属性之后,我们分别要对Room与User进行save(),在对象的关 系图上,基本上我们应实现的是储存User,而Room的持久化应自动完成,而不用我们再特地指定,为了达到这个目的,我们在映射多对一关系时可以使用 cascade来指定自动持久化的方式,例如修改User.hbm.xml为:

    User.hbm.xml

    <many-to-one name="room"

                         column="ROOM_ID"

                         class="onlyfun.caterpillar.Room"

                         cascade="save-update"/>


     预设上cascade是none,也就是不进行自动持久化,所以预设上我们必须对每一个要持久化的对象进行save(),在上面我们指定了cascade为save-update,这表示当我们储存或更新User时,自动对其所关联到的Room(暂时)对象进行持久化。
      这边要注意的是,使用cascade自动持久化时,会先检查被关联对象的id属性,未被持久化的对象之id属性是由unsaved-value决定,预设 是null,如果您使用long这样的原生型态(primitive type)时,则必须自行指定默认值,所以在「多对一实体映像」的Room.hbm.xml的id映像上,我们必须改为:

    Room.hbm.xml

    <id name="id" column="ROOM_ID" unsaved-value="0">

                <generator class="increment"/>

            </id>


     如果您不想额外设定unsaved-value信息,则可以将long改为Long,这可以符合预设的unsaved-value为null的设定,关于unsaved-value进一步的介绍,可以参考这边:
    http://www.hibernate.org.cn/76.html
     修改映像文件之后,我们可以使用以下的方式来储存数据:

    HibernateTest.java

    import onlyfun.caterpillar.*;

    import net.sf.hibernate.*;

    import net.sf.hibernate.cfg.*;

     

    public class HibernateTest {

        public static void main(String[] args) throws HibernateException {

            SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

        

            Room room1 = new Room();

            room1.setAddress("NTU-M8-419");

          

            User user1 = new User();

            user1.setName("bush");

            user1.setRoom(room1);

          

            User user2 = new User();

            user2.setName("caterpillar");

            user2.setRoom(room1);

          

            Session session = sessionFactory.openSession();

            Transaction tx= session.beginTransaction();

          

            session.save(user1);

            session.save(user2);

     

            tx.commit();

            session.close();

     

            sessionFactory.close();

        }

    }


     这次我们不用特地储存room了,透过cascade设定为save-update,被User关联到的对象,在储存或更新时,都会自动持久化,之后我们甚至可以如下来进行对象储存:

    Transaction tx = session.beginTransaction();

    User user = (User) session.get(User.class, new Long(1));

    Room room = new Room();

    room.setAddress("NTU-M5-105");

    user.setRoom(room);

    tx.commit();

    session.close();


     cascade的指定除了save-update之外,还可以使用delete、all、all-delete- orphan、delete- orphan,各个设定的作用,建议您查看参考手册9.8Lifecyles and object graphs,当中有详细的说明,而有关于可达性完成持久化(Persistence by reachability)的说明,可以参考Hibernate in Action的4.3。

    发表于 @ 2005年01月27日 20:28:00|编辑

    新一篇: Hibernate入门21 - 双向关联与inverse设定 | 旧一篇: Hibernate入门19 - 一对多实体映像

    评论:没有评论。

    发表评论  


    当前用户设置只有注册用户才能发表评论。如果你没有登录,请点击登录
    Csdn Blog version 3.1a
    Copyright © chho