* fetch={select/join},默认为select。
* fetch="select" 表示另外发送一条sql语句进行关联查询。
* fetch="join" 表示进行表连接查询。设置为join时,lazy=true失去作用。
* inverse控制的关联关系更新在session.flush时执行,所以在save/update时引发更新关联关系的
insert/update/delete sql总是在最后执行。delete时引发的更新关联关系的update/delete sql总是在
最前面执行。
* inverse 只对one2many many2many有效,对many2one one2one 无效。
由于one方维护关联关系时会发出update更新sql,所以通常在many方维护关联关系。
* cascade 一般不对many2one,many2many,constrained=true的one2one 设置级联删除。
* cascade几种取值:
save-update: 级联保存(load以后如果子对象发生了更新,也会级联更新). 但它不会级联删除
delete: 级联删除, 但不具备级联保存和更新
all-delete-orphan: 在解除父子关系时,自动删除不属于父对象的子对象, 也支持级联删除和级联保存更新.
all: 级联删除, 级联更新,但解除父子关系时不会自动删除子对象.
delete-orphan: 删除所有和当前对象解除关联关系的对象
* 在one2many和many2many的set中设置cascade="all-delete-orphan" 时,在update/flush/commit的
时候不能直接设置clazz.setStudents(null);
会引发异常:A collection with cascade="all-delete-orphan" was no longer referenced by the owning
entity instance。delete操作时,可以直接设置null,这样只会删除clazz表和更新Student表记录。
新建one时,可以设置clazz.setStudents(null);这样只会保存clazz表记录。
* one2many 单向关联:
<set name="students" cascade="save-update">
<key>
<column name="clazz_id" length="32" />
</key>
<one-to-many class="com.jaeson.hibernatestudy.bean.Student" />
</set>
若set设置inverse="true"时,将由多方Student维护关联关系,由于是单向关联,所以多方Student将无法
维护外键,即clazz_id将为null。
缺省inverse="false" 表示由一方Clazz维护外键关联关系,所以在保存时会发出update语句用于更新
Student的外键clazz_id。
当执行session.save(student)时,若clazz_id为not-null,此时将会出项插入异常,所以在one2many单向
关联时需要设置外键clazz_id的属性为not-null="false"。
cascade="save-update" 表示保存Clazz时级联保存Set里关联的Student对象,通常用于<Set>等集合
关联。若没有设置cascade属性,则必须显式保存Student对象session.save(student),否则Clazz在维护
关联关系时会抛出org.hibernate.TransientObjectException异常。
Hibernate: insert into db4myeclipse.clazz (name, id) values (?, ?)
Hibernate: insert into db4myeclipse.student (name, sex, id) values (?, ?, ?)
Hibernate: update db4myeclipse.student set clazz_id=? where id=?
* many2one 单向关联:
需要先保存一方Clazz,再保存多方Student,这样只会有2条insert sql。否则会引发2条insert和一个
update关联关系的sql。
<many-to-one name="clazz" class="com.jaeson.hibernatestudy.bean.Clazz" fetch="join">
<column name="clazz_id" length="32" not-null="true" />
</many-to-one>
fetch="join"时,lazy="true"失去效果,将会和Student一起进行inner join查询。
由于是由多方Student维护外键关联关系,所以外键clazz_id可以设置为not-null="true"。
在保存时需要先保存关联对象Clazz:
session.save(clazz);
session.save(student);
否则Student在维护关联关系时会抛出:
org.hibernate.action.internal.UnresolvedEntityInsertActions异常。
Attempting to save one or more entities that have a non-nullable association with an unsaved
transient entity.
Hibernate: insert into db4myeclipse.clazz (name, id) values (?, ?)
Hibernate: insert into db4myeclipse.student (clazz_id, name, sex, id) values (?, ?, ?, ?)
* many2one 双向关联:
<set name="students" cascade="save-update" inverse="true">
<key>
<column name="clazz_id" length="32" not-null="true" />
</key>
<one-to-many class="com.jaeson.hibernatestudy.bean.Student" />
</set>
<many-to-one name="clazz" class="com.jaeson.hibernatestudy.bean.Clazz" fetch="join">
<column name="clazz_id" length="32" not-null="true" />
</many-to-one>
fetch="join"时,lazy="true"失去效果,将会和Student一起进行inner join查询。
由于设置了inverse="true",所以将由多方Student维持关联关系。
没有设置cascade时必须先保存Clazz对象,再保存Student对象;否则会抛出
org.hibernate.action.internal.UnresolvedEntityInsertActions异常。
Attempting to save one or more entities that have a non-nullable association with an unsaved
transient entity.
若Clazz设置了cascade="save-update"时,可以只执行session.save(clazz)。
Hibernate: insert into db4myeclipse.clazz (name, id) values (?, ?)
Hibernate: insert into db4myeclipse.student (clazz_id, name, sex, id) values (?, ?, ?, ?)