hibernate设置inverse 、cascade 、fetch

  * 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 (?, ?, ?, ?)

猜你喜欢

转载自jaesonchen.iteye.com/blog/2287423