大部分摘自: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),并且应在“一”方指定相应的级联操作。