Hibernate 学习笔记3 inverse和 cascade

大部分摘自:http://www.javaeye.com/topic/314785

 

这两个属性都用于一多对或者多对多的关系中。而inverse特别是用于双向关系,在单向关系中我们并不需要。

 

Cascade代表是否执行级联操作,Inverse代表是否由己方维护关系。

 

Cascade:

 

Cascade属性的可能值有

    all: 所有情况下均进行关联操作,即save-update和delete。
    none: 所有情况下均不进行关联操作。这是默认值。
    save-update: 在执行save/update/saveOrUpdate时进行关联操作。
    delete: 在执行delete 时进行关联操作。

    all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点。比如在一个一对多的关系中,Student包含多个book,当在对象关系中删除一个book时,此book即成为孤儿节点。

 

Inverse:

 

Inverse属性的可能值是true或者false,默认为false:

 

     false代表由己方来维护关系,true代表由对方来维护关系。在一个关系中,只能由一方来维护关系,否则会出问题(解疑中会讲到);同时也必须由一方来维护关系,否则会出现双方互相推卸责任,谁也不管。

 

一多对的例子:

 

有两个类,Father和Child,是一对多的关系。下面这段hbm配置是从Father.hbm.xml中摘取的。

 

1.  cascade="all" inverse="true"

 

<set name="children" table="child" cascade="all" inverse="true">
            <!-- 这里的father_id在数据库表中是 child表的字段 -->
            <key column="father_id"></key>
            <one-to-many class="org.py.hib.relation.one2many.Child"/>

</set>

 

inverse="true" 代表由Child来维护关系,而Child类中不包含Father属性

 

public class Child {
    private String id;
    private String name;

}

 

在One2ManyTest类中的代码如下:

Father father=new Father();
        father.setName("sunyi");
       
        Child child1=new Child();
        child1.setName("aaa");
       
        Child child2=new Child();
        child2.setName("bbb");
       
        Child child3=new Child();
        child3.setName("ccc");
       
        father.getChildren().add(child1);  //Father类中含有 private Set<Child> children=new HashSet<Child>();
        father.getChildren().add(child2);
        father.getChildren().add(child3);
       
        Session session=null;
        Transaction trans=null;
        try{
            session=factory.openSession();
            trans=session.beginTransaction();
            session.save(father);
            trans.commit();

        }

 

测试结果,生成的sql语句如下:

Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, id) values (?, ?)
Hibernate: insert into child (name, id) values (?, ?)
Hibernate: insert into child (name, id) values (?, ?)

 

数据库中的child表中father_id字段为空置。

 

2. cascade="all" inverse="false"

 

inverse="false" 代表由Father本身来维护关系

 

测试结果,生成的sql语句如下:

Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, id) values (?, ?)
Hibernate: insert into child (name, id) values (?, ?)
Hibernate: insert into child (name, id) values (?, ?)
Hibernate: update child set father_id=? where id=?
Hibernate: update child set father_id=? where id=?
Hibernate: update child set father_id=? where id=?

结果一切正常。

 

3. cascade="none" inverse="true"

    cascade="none" 所有情况下均不进行关联操作。这是默认值。

    inverse="true"  由Child来维护关系

 

测试结果,生成的sql语句如下:

  Hibernate: insert into father (name, id) values (?, ?)

 

 

4. cascade="none" inverse="false"

    inverse="false"  由Father来维护关系

 

 

测试结果,生成的sql语句如下:

  Hibernate: insert into father (name, id) values (?, ?)
  Hibernate: update child set father_id=? where id=?

  抛出异常,数据回滚,Father Child 表中无数据

  因为child表中无数据,所以Father来维护关系的时候出现异常

 

悲哀啊 ,悲哀啊   测试了这么久,跟原帖内容不一样,自己也纳闷为什么不一样。

原来漏掉了  而inverse特别是用于双向关系,在单向关系中我们并不需要。 切记 切记

 

下面在Child端加上   private Father father;

Child.hbm.xml中的部分代码为:

<many-to-one name="father" class="org.py.hib.relation.one2many.Father" column="father_id" ></many-to-one>

 

1.  cascade="all" inverse="true"

     由Child端来维护关系.

 

生成的sql语句如下:

Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)

 

2. cascade="all" inverse="false"

     由Father端来维护关系

 

生成的sql语句如下:

Hibernate: insert into father (name, id) values (?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: insert into child (name, father_id, id) values (?, ?, ?)
Hibernate: update child set father_id=? where id=?  //多余的
Hibernate: update child set father_id=? where id=?  //多余的
Hibernate: update child set father_id=? where id=?  //多余的 

 

是不是可以得出这样的结论:  这样的组合不怎么好????

 

3. cascade="none" inverse="true"

    none: 所有情况下均不进行关联操作。这是默认值。

    inverse="true": 由Child来维护关系

 

   生成的sql语句如下:

Hibernate: insert into father (name, id) values (?, ?)

 

4. cascade="none" inverse="false"

    inverse="false": 由Father来维护关系(这不是等同于单向关联吗?)

 

   生成的sql语句如下:

     Hibernate: insert into father (name, id) values (?, ?)
     Hibernate: update child set father_id=? where id=?

 

  抛出异常,数据回滚,Father Child 表中无数据

  因为child表中无数据,所以Father来维护关系的时候出现异常

 

 

 

总结:可以看到,对于一对多关系,关系应由“多”方来维护(指定“一”方的inverse为true),并且应在“一”方指定相应的级联操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值