Hibernate中inverse="true"的理解
举例如下
转自:http://lijiejava.iteye.com/blog/776587
Customer类:
- public class Customer {
- private int id;
- private String name;
- private Set orders = new HashSet();
- •••
- }
即Customer类具有一个set集合属性orders,其中Order是一个普通的类:
- public class Order {
- private int id;
- private String orderName;
- •••
- }
数据库中表的结构:
- t_customer: 两个字段:id name
- t_order: 三个字段:id orderName customerid
Customer类的映射文件:Customer.hbm.xml (Order类的映射文件忽略)
- <hibernate-mapping>
- <class name="test.Customer" table="t_customer" lazy="false">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="name"/>
- <set name="orders" cascade="save-update" lazy="false">
- <key column="customerid"/>
- <one-to-many class="test.Order"/>
- </set>
- </class>
- </hibernate-mapping>
执行如下代码:
- Set orders = new HashSet();
- Order o1 = new Order();
- o1.setOrderName("o1");
- Order o2 = new Order();
- o2.setOrderName("o2");
- orders.add(o1);
- orders.add(o2);
- Customer c = new Customer();
- c.setName("aaa");
- c.setOrders(orders);
- session.save(c);
此时Hibernate发出的sql语句如下:
- Hibernate: insert into t_customer (name) values (?)
- Hibernate: insert into t_order (orderName) values (?)
- Hibernate: insert into t_order (orderName) values (?)
- Hibernate: update t_order set customerid=? where id=?
- Hibernate: update t_order set customerid=? where id=?
查看数据库:
- t_customer : t_order:
- id | name id | orderName | customerid
- 1 aaa 1 o1 1
- 2 o2 1
保存Customer对象时,首先发出insert into t_customer (name) values
(?)语句将c同步到数据库,由于在<set>映射中设置cascade="save-update",所以会同时保存orders集合中的
Order类型的o1,o2对象(如果没有这个设置,即cascade="save-update"),那么Hibenrate不会自动保存orders
集合中的对象,那么在更新时将会抛出如下异常:
- Hibernate: insert into t_customer (name) values (?)
- Hibernate: update t_order set customerid=? where id=?
- org.hibernate.TransientObjectException: test.Order
- ••••••
抛出这一异常的原因是:<set>映射默认"inverse=fasle"即由Customer对象作为主控方,那么它要负责关联的
维护工作,在这里也就是负责更新t_order表中的customerid字段的值,但由于未设置cascade="save-update",所以
orders集合中的对象不会在保存customer时自动保存,因此会抛出异常(如果未设置,需要手动保存)。
现在设置cascade="save-update",同时设置inverse="true",即:
- •••
- <set name="orders" cascade="save-update" inverse="true" lazy="false">
- <key column="customerid"/>
- <one-to-many class="test.Order"/>
- </set>
- •••
同样执行上述代码,发出如下语句:
- Hibernate: insert into t_customer (name) values (?)
- Hibernate: insert into t_order (orderName) values (?)
- Hibernate: insert into t_order (orderName) values (?)
相比上一次执行,少了两条update语句,查看数据库:
- t_customer : t_order:
- id | name id | orderName | customerid
- 1 aaa 1 o1 NULL
- 2 o2 NULL
发现t_order表中customerid的值为NULL,这是由于设置了inverse="true",它意味着
Customer不再作为主控方,而将关联关系的维护工作交给关联对象Orders来完成。在保存Customer时,Customer不在关心
Orders的customerid属性,必须由Order自己去维护,即设置order.setCustomer(customer);
如果需要通过Order来维护关联关系,那么这个关联关系转换成双向关联。
修改Order类代码:
- public class Order {
- private int id;
- private String orderName;
- private Customer customer;
- •••
- }
Order.hbm.xml:
- <hibernate-mapping>
- <class name="test.Order" table="t_order">
- <id name="id">
- <generator class="native"/>
- </id>
- <property name="orderName"/>
- <many-to-one name="customer" column="customerid"/>
- </class>
- </hibernate-mapping>
此时数据库中表的结构不会变化。
再次执行上述代码,发出如下sql语句:
- Hibernate: insert into t_customer (name) values (?)
- Hibernate: insert into t_order (orderName, customerid) values (?, ?)
- Hibernate: insert into t_order (orderName, customerid) values (?, ?)
发现在保存Order对象时为customerid字段赋值,因为Order对象中拥有Customer属性,对应customerid字段,查看数据库表:
- t_customer : t_order:
- id | name id | orderName | customerid
- 1 aaa 1 o1 NULL
- 2 o2 NULL
发现customerid的值仍为NULL,因为在上述代码中并未设置Order对象的Customer属性值,由于设置了inverse="true",所以Order对象需要维护关联关系,所以必须进行设置,即
order.setCustomer(customer);
修改上述代码为:
- •••
- Customer c = new Customer();
- Set orders = new HashSet();
- Order o1 = new Order();
- o1.setOrderName("o1");
- o1.setCustomer(c);
- Order o2 = new Order();
- o2.setOrderName("o2");
- o2.setCustomer(c);
- orders.add(o1);
- orders.add(o2);
- c.setName("aaa");
- c.setOrders(orders);
- session.save(c);
- •••
执行上述代码,发出如下语句:
- Hibernate: insert into t_customer (name) values (?)
- Hibernate: insert into t_order (orderName, customerid) values (?, ?)
- Hibernate: insert into t_order (orderName, customerid) values (?, ?)
查看数据库:
- t_customer : t_order:
- id | name id | orderName | customerid
- 1 aaa 1 o1 1
- 2 o2 1
发现已经设置了customerid的值。
在一对多关联中,在多的一方设置inverse="true",有助于性能的改善。通过上述分析可以发现少了update语句。
Hibernate中inverse="true"的理解的更多相关文章
- hibernate中 inverse的用法(转载)
http://blog.csdn.net/xiaoxian8023/article/details/15380529 一.Inverse是hibernate双向关系中的基本概念.inverse的真正作 ...
- Hibernate中inverse属性与cascade属性
Hibernate集合映射中,经常会使用到"inverse"和"cascade"这两个属性.对于我这样,Hibernate接触不深和语文水平够烂的种种因素,发现 ...
- Hibernate中inverse、cascade的说明
一: 前沿:刚刚学习hibernate时,对于inverse很是纠结,不知道什么时候该用什么时候不该用,在网上找了一些资料,说的也很含糊,我都不知道如果写了"inverse=true&quo ...
- 由hibernate配置inverse="true"而导致的软件错误,并分析解决此问题的过程
题目背景软件是用来做安装部署的工具,在部署一套系统时会有很多安装包,通过此工具,可以生成一个xml文件用以保存每个安装包的文件位置.顺序.参数.所需脚本.依赖条件验证(OS..net.IIS.数据版本 ...
- 一口一口吃掉Hibernate(八)——Hibernate中inverse的用法
一.Inverse是hibernate双向关系中的基本概念.inverse的真正作用就是指定由哪一方来维护之间的关联关系.当一方中指定了“inverse=false”(默认),那么那一方就有责任负责之 ...
- 在 Hibernate 中inverse的属性
hibernate配置文件中有这么一个属性inverse,它是用来指定关联的控制方的.inverse属性默认是false,若为false,则关联由自己控制,若为true,则关联由对方控制.见例子: 一 ...
- hibernate之inverse=true相关配置讲解
首先inverse=”true”是在双向关联里面使用单向关联没有这个配置 inverse – 标记由哪一方来维护关联关系(双向关联中会用到) inverse默认值为false 如果inverse设 ...
- hibernate中inverse作用
默认 inverse="false"即该元素指向的类负责维护该关系. 如: <hibernate-mapping> <class name="com.h ...
- Hibernate中的一些关键字理解
ORM的理解: ORM(Object/Relation Mapping): 对象/关系映射ORM 主要解决对象-关系的映射: ORM的思想:将关系数据库中表中的记录映射成为对象,以对象的形式展现,程序 ...
随机推荐
- java常量池概念【转】
http://blog.csdn.net/olanlanxiari/article/details/8104505
- Zookeeper+Kafka的单节点配置
Zookeeper+Kafka的单节点配置 环境描述:Ubuntu16.04 server系统,在系统上搭建Java环境,jdk的版本为1.8或更高,我的服务器IP地址为192.168.0.106. ...
- 守护进程,进程安全,IPC进程间通讯,生产者消费者模型
1.守护进程(了解)2.进程安全(*****) 互斥锁 抢票案例3.IPC进程间通讯 manager queue(*****)4.生产者消费者模型 守护进程 指的也是一个进程,可以守护着另一个进程 一 ...
- rootfls(根操作系统)
rootfs根文件系统,linux下的任何目录都是rootfs的一个路径 Files 文件 Directory 目录 FHS(文件层级标准)规定了linux发行标准,也就是一些固定的文件存储 文件 ...
- 裸机——I2C 2
前面的随笔完成了I2C时序分析(不涉及仲裁) 现在可以学使用控制器的I2C了. 1.先回顾I2C的基础知识 (1)总线包括SCL + SDA. (2)通信的特点: 同步,串行,电平 所以决定了 I2C ...
- 一行代码将两个列表拼接出第三个列表(两个可迭代对象相加产生第三个可迭代对象)--map()方法
map()方法 map(func, *iterables) --> map object lambda方法: lambda 参数 :返回值 a = map(',7]) print(list(a ...
- 7.Mongodb安全性流程
1.安全性流程 2.超级管理员 为了更安全的访问mongodb,需要访问者提供用户名和密码,于是需要在mongodb中创建用户 采用了角色-用户-数据库的安全管理方式 常用系统角色如下: root:只 ...
- leetcode 【 Remove Duplicates from Sorted List 】 python 实现
题目: Given a sorted linked list, delete all duplicates such that each element appear only once. For e ...
- 每天一个Linux命令(3):ls命令
ls命令用来显示目标列表,在Linux中是使用率较高的命令.ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件. 语法 ls(选项)(参数) 选项 -a:显示所有档案及目录(ls内定将档案名 ...
- PyCharm 解决有些库(函数)没有代码提示
问题描述: 如图,当输入 im. 没有智能提示第三库相应的函数或其他提示. 解决方案: python是动态强类型语言,IDE无法判断Image.open("panda.png")的 ...