Hibernate中inverse的用法

来源:互联网 发布:云计算基础知识考题 编辑:程序博客网 时间:2024/06/06 03:34
我就one-to-many来做个简单说明: [code:1] 
Parent parent = (Parent) session.load(Parent.class, pid); session.delete(parent);
[/code:1] 1. 爸爸那边设置了cascade=all和inverse=true a. delete from children b. delete from parent 2. 爸爸那边设置了cascade=all,没有设inverse=true a. update children set parent_id=null where parent_id=? b. delete from children c. delete from parent 因为此时inverse=false,所以爸爸要负责维护relationship,所以它要去把children中的连接信息都清空。但是,如 果children的parent_id的constraint设置的是not-null的话,那么很不幸,hibernate执行到2.a就会 throw exception了。 如果你要问,这个inverse=true到底是在源代码中的哪儿判断的呀?请看代码: [code:1] ...... SessionImpl.flush(); SessionImpl.execute(); SessionImpl.executeAll(collectionRemovals); executable.execute(); ScheduledCollectionRemove.execute(); getPersister().remove( getId(), getSession() ); OneToManyPersister(即AbstractCollectionPersister).remove(); if ( !isInverse ) { PreparedStatement st = session.getBatcher().prepareBatchStatement( getSQLDeleteString() ); } OneToManyPersister.getSQLDeleteString(); return "update children set parent_id=null where parent_id=?"; ...... [/code:1] ======================================================================== 2、到底在哪用inverse="ture"?   

   “set的inverse属性决定是否把对set的改动反映到数据库中去。inverse=false————反映;inverse=true————不反映”inverse属性默认为false

    

  inverse属性默认是false的,就是说关系的两端都来维护关系。这个意思就是 说,如有一个Student,   Teacher和TeacherStudent表,Student和Teacher是多对多对多关系,这个关系由 TeacherStudent这个表来表 现。那么什么时候插入或删除TeacherStudent表中的记录来维护关系呢?在用hibernate时, 我们不会显示的对 TeacherStudent表做操作。对TeacherStudent的操作是hibernate帮我们做的。hibernate就 是看hbm文件中指 定的是"谁"维护关系,那个在插入或删除"谁"时,就会处发对关系表的操作。前提是"谁"这个对象已经知道这个关系了,就是说关系另 一头的对象已经set 或是add到"谁"这个对象里来了。前面说过inverse默认是false,就是关系的两端都维护关系,对其中任一个操作都会处 发对表系表的操作。当在 关系的一头,如Student中的bag或set中用了inverse="true"时,那就代表关系是由另一关维护的 (Teacher)。就是说当这插 入Student时,不会操作TeacherStudent表,即使Student已经知道了关系。只有当 Teacher插入或删除时才会处发对关系表的 操作。所以,当关系的两头都用inverse="true"是不对的,就会导致任何操作都不处发对关系表 的操作。当两端都是inverse= "false"或是default值是,在代码对关系显示的维护也是不对的,会导致在关系表中插入两次关系。   

    

  在一对多关系中inverse就更有意义了。在多对多中,在哪端 inverse="true"效果差不多(在效率上)。但是在一对多中,如果要一方维护关 系,就会使在插入或是删除"一"方时去update"多"方的 每一个与这个"一"的对象有关系的对象。而如果让"多"方面维护关系时就不会有update 操作,因为关系就是在多方的对象中的,直指插入或是删除多方 对象就行了。当然这时也要遍历"多"方的每一个对象显示的操作修关系的变化体现到DB中。不管 怎样说,还是让"多"方维护关系更直观一些。

    (1)对one-to-many而言,改变set,会让hibernate执行一系列的update语句, 不会delete/insert数据

    (2)对many-to-many而言,改变set,只修改关系表的数据,不会影响many-to-many的另一方。

    (3)虽然one-to-many和many-to-many的数据库操作不一样,但目的都是一个:维护数据的一致性。
原创粉丝点击