举例如下

转自:http://lijiejava.iteye.com/blog/776587

Customer类:

  1. public class Customer {
  2. private int id;
  3. private String name;
  4. private Set orders = new HashSet();
  5. •••
  6. }

即Customer类具有一个set集合属性orders,其中Order是一个普通的类:

  1. public class Order {
  2. private int id;
  3. private String orderName;
  4. •••
  5. }

数据库中表的结构:

  1. t_customer:  两个字段:id  name
  2. t_order:     三个字段:id  orderName  customerid

Customer类的映射文件:Customer.hbm.xml  (Order类的映射文件忽略)

  1. <hibernate-mapping>
  2. <class name="test.Customer" table="t_customer" lazy="false">
  3. <id name="id">
  4. <generator class="native"/>
  5. </id>
  6. <property name="name"/>
  7. <set name="orders"  cascade="save-update"  lazy="false">
  8. <key column="customerid"/>
  9. <one-to-many class="test.Order"/>
  10. </set>
  11. </class>
  12. </hibernate-mapping>

执行如下代码:

  1. Set orders = new HashSet();
  2. Order o1 = new Order();
  3. o1.setOrderName("o1");
  4. Order o2 = new Order();
  5. o2.setOrderName("o2");
  6. orders.add(o1);
  7. orders.add(o2);
  8. Customer c = new Customer();
  9. c.setName("aaa");
  10. c.setOrders(orders);
  11. session.save(c);

此时Hibernate发出的sql语句如下:

  1. Hibernate: insert into t_customer (name) values (?)
  2. Hibernate: insert into t_order (orderName) values (?)
  3. Hibernate: insert into t_order (orderName) values (?)
  4. Hibernate: update t_order set customerid=? where id=?
  5. Hibernate: update t_order set customerid=? where id=?

查看数据库:

  1. t_customer :                    t_order:
  2. id   |  name                   id   |   orderName   |   customerid
  3. 1       aaa                    1           o1              1
  4. 2           o2              1

保存Customer对象时,首先发出insert into t_customer (name) values
(?)语句将c同步到数据库,由于在<set>映射中设置cascade="save-update",所以会同时保存orders集合中的
Order类型的o1,o2对象(如果没有这个设置,即cascade="save-update"),那么Hibenrate不会自动保存orders
集合中的对象,那么在更新时将会抛出如下异常:

  1. Hibernate: insert into t_customer (name) values (?)
  2. Hibernate: update t_order set customerid=? where id=?
  3. org.hibernate.TransientObjectException: test.Order
  4. ••••••

抛出这一异常的原因是:<set>映射默认"inverse=fasle"即由Customer对象作为主控方,那么它要负责关联的
维护工作,在这里也就是负责更新t_order表中的customerid字段的值,但由于未设置cascade="save-update",所以
orders集合中的对象不会在保存customer时自动保存,因此会抛出异常(如果未设置,需要手动保存)。

现在设置cascade="save-update",同时设置inverse="true",即:

  1. •••
  2. <set name="orders" cascade="save-update" inverse="true" lazy="false">
  3. <key column="customerid"/>
  4. <one-to-many class="test.Order"/>
  5. </set>
  6. •••

同样执行上述代码,发出如下语句:

  1. Hibernate: insert into t_customer (name) values (?)
  2. Hibernate: insert into t_order (orderName) values (?)
  3. Hibernate: insert into t_order (orderName) values (?)

相比上一次执行,少了两条update语句,查看数据库:

  1. t_customer :                    t_order:
  2. id   |  name                   id   |   orderName   |   customerid
  3. 1       aaa                    1           o1              NULL
  4. 2           o2              NULL

发现t_order表中customerid的值为NULL,这是由于设置了inverse="true",它意味着

Customer不再作为主控方,而将关联关系的维护工作交给关联对象Orders来完成。在保存Customer时,Customer不在关心
Orders的customerid属性,必须由Order自己去维护,即设置order.setCustomer(customer);

如果需要通过Order来维护关联关系,那么这个关联关系转换成双向关联。

修改Order类代码:

  1. public class Order {
  2. private int id;
  3. private String orderName;
  4. private Customer customer;
  5. •••
  6. }

Order.hbm.xml:

  1. <hibernate-mapping>
  2. <class name="test.Order" table="t_order">
  3. <id name="id">
  4. <generator class="native"/>
  5. </id>
  6. <property name="orderName"/>
  7. <many-to-one name="customer" column="customerid"/>
  8. </class>
  9. </hibernate-mapping>

此时数据库中表的结构不会变化。

再次执行上述代码,发出如下sql语句:

  1. Hibernate: insert into t_customer (name) values (?)
  2. Hibernate: insert into t_order (orderName, customerid) values (?, ?)
  3. Hibernate: insert into t_order (orderName, customerid) values (?, ?)

发现在保存Order对象时为customerid字段赋值,因为Order对象中拥有Customer属性,对应customerid字段,查看数据库表:

  1. t_customer :                    t_order:
  2. id   |  name                   id   |   orderName   |   customerid
  3. 1       aaa                    1           o1              NULL
  4. 2           o2              NULL

发现customerid的值仍为NULL,因为在上述代码中并未设置Order对象的Customer属性值,由于设置了inverse="true",所以Order对象需要维护关联关系,所以必须进行设置,即

order.setCustomer(customer);

修改上述代码为:

  1. •••
  2. Customer c = new Customer();
  3. Set orders = new HashSet();
  4. Order o1 = new Order();
  5. o1.setOrderName("o1");
  6. o1.setCustomer(c);
  7. Order o2 = new Order();
  8. o2.setOrderName("o2");
  9. o2.setCustomer(c);
  10. orders.add(o1);
  11. orders.add(o2);
  12. c.setName("aaa");
  13. c.setOrders(orders);
  14. session.save(c);
  15. •••

执行上述代码,发出如下语句:

  1. Hibernate: insert into t_customer (name) values (?)
  2. Hibernate: insert into t_order (orderName, customerid) values (?, ?)
  3. Hibernate: insert into t_order (orderName, customerid) values (?, ?)

查看数据库:

  1. t_customer :                    t_order:
  2. id   |  name                   id   |   orderName   |   customerid
  3. 1       aaa                    1           o1              1
  4. 2           o2              1

发现已经设置了customerid的值。

在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。

Hibernate中inverse="true"的理解的更多相关文章

  1. hibernate中 inverse的用法(转载)

    http://blog.csdn.net/xiaoxian8023/article/details/15380529 一.Inverse是hibernate双向关系中的基本概念.inverse的真正作 ...

  2. Hibernate中inverse属性与cascade属性

    Hibernate集合映射中,经常会使用到"inverse"和"cascade"这两个属性.对于我这样,Hibernate接触不深和语文水平够烂的种种因素,发现 ...

  3. Hibernate中inverse、cascade的说明

    一: 前沿:刚刚学习hibernate时,对于inverse很是纠结,不知道什么时候该用什么时候不该用,在网上找了一些资料,说的也很含糊,我都不知道如果写了"inverse=true&quo ...

  4. 由hibernate配置inverse="true"而导致的软件错误,并分析解决此问题的过程

    题目背景软件是用来做安装部署的工具,在部署一套系统时会有很多安装包,通过此工具,可以生成一个xml文件用以保存每个安装包的文件位置.顺序.参数.所需脚本.依赖条件验证(OS..net.IIS.数据版本 ...

  5. 一口一口吃掉Hibernate(八)——Hibernate中inverse的用法

    一.Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之 ...

  6. 在 Hibernate 中inverse的属性

    hibernate配置文件中有这么一个属性inverse,它是用来指定关联的控制方的.inverse属性默认是false,若为false,则关联由自己控制,若为true,则关联由对方控制.见例子: 一 ...

  7. hibernate之inverse=true相关配置讲解

      首先inverse=”true”是在双向关联里面使用单向关联没有这个配置 inverse – 标记由哪一方来维护关联关系(双向关联中会用到) inverse默认值为false 如果inverse设 ...

  8. hibernate中inverse作用

    默认 inverse="false"即该元素指向的类负责维护该关系. 如: <hibernate-mapping> <class name="com.h ...

  9. Hibernate中的一些关键字理解

    ORM的理解: ORM(Object/Relation Mapping): 对象/关系映射ORM 主要解决对象-关系的映射: ORM的思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序 ...

随机推荐

  1. hdu1251统计难题(trie)

    统计难题 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)Total Submi ...

  2. Android 布局跟着NAVIGATION_BAR 重新布局

    要想让自己的布局跟着NAVIGATION_BAR 的变化重新布局,就不要设置 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION. 这个FLAG. 这个flag 设置之后,你的 ...

  3. python的高阶函数与匿名函数

    一.高阶函数的定义 高阶函数:就是把函数当成参数传递的一种函数,例如: def add(x,y,f): return f(x)+f(y) print(add(-8,11,abs) 结果:19 解释: ...

  4. DJango跨域中间键

    Skip to main content   Search PyPISearch Help Donate Log in Register django-cors-middleware 1.3.1 pi ...

  5. 《Cracking the Coding Interview》——第11章:排序和搜索——题目2

    2014-03-21 20:49 题目:设计一种排序算法,使得anagram排在一起. 解法:自定义一个comparator,使用额外的空间来统计字母个数,然后比较字母个数. 代码: // 11.2 ...

  6. SVN迁移到Git原因说明

    1.Git分布式的源码管理 每位开发人员计算机本地会有一份代码库,开发人员可在不受其他人代码提交影响的前提下对源码进行提交/回滚/撤销等操作. 在独立的开发任务中即可实现对源码管理又不受其他开发人员提 ...

  7. .net面试那些事

    2014-3-30这天从昆明来到了江苏无锡,一周时间,不同地方不同感触. 在经过长达35小时的火车,在上海南见到了我弟,在经过两小时汽车到了无锡.回想起来....在坐汽车途中,虽然自己已很累,但从上海 ...

  8. loadrunner 欺骗ip设置

    工具准备:loadrunner12,windows 10 ip欺骗=ip wizard 前提条件:本机IP地址为固定地址,不是自动获取的地址 方法: 1.管理员身份打开cmd 2.输入命令:confi ...

  9. Metaspolit

    Metaspolit介绍 Metasploit是一款开源的安全漏洞检测工具,安全工作人员常用 Metasploit工具来检测系统的安全性.Metasploit Framework (MSF) 在200 ...

  10. Spring 学习笔记(六)—— AOP的简单理解

    系统中的业务可以分为核心关注点和横切关注点. 核心关注点时业务处理的主要流程,而横切关注点是与核心业务无关但更为通用的业务. 各个横切关注点离散地穿插于核心业务之中,导致系统地每一个模块都与这些业务具 ...