- 浏览: 804249 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (360)
- Java (101)
- JPA/Hibernate (10)
- Spring (14)
- Flex/BlazeDS (37)
- Database (30)
- Lucene/Solr/Nutch (0)
- Maven/Ant (25)
- CXF/WebService (3)
- RPC/RMI/SOAP/WSDL (1)
- REST (6)
- TDD/BDD/JUnit (1)
- Servlet/JSP (2)
- AI/MachineLearning (3)
- Resource (1)
- 字符编码 (2)
- OOA/OOPS/UML (5)
- DesignPattern (8)
- 算法与数据结构 (11)
- Web&App Server (13)
- 并发&异步&无阻塞 (7)
- Entertainment (4)
- JavaScript/ExtJS (45)
- CodeStyle&Quality (1)
- svn/git/perforce (8)
- JSON (2)
- JavaScriptTesting (4)
- Others (6)
- RegularExpression (2)
- Linux/Windows (12)
- Protocal (2)
- Celebrities (1)
- Interview (1)
- 计算机语言 (1)
- English (2)
- Eclipse (5)
- TimeZone/时区 (1)
- Finance (1)
- 信息安全 (1)
- JMS/MQ (2)
- XSD/XML/DTD (3)
- Android (4)
- 投资 (3)
- Distribution (3)
- Excel (1)
最新评论
-
qdujunjie:
如果把m换成具体的数字,比如4或者5,会让读者更明白
m阶B树中“阶”的含义 -
java-admin:
不错,加油,多写点文章
关于Extjs的mixins和plugin -
xiehuaidong880827:
你好,我用sencha cmd打包完本地工程后,把app.js ...
ExtJS使用Sencha Cmd合并javascript文件为一个文件 -
KIWIFLY:
lwpan 写道inverse = "true&qu ...
Hibernate中什么时候使用inverse=true -
luedipiaofeng:
good
消除IE stop running this script弹出框
inverse=true含义:
关系(Relationship)由两方组成,其中被定义了inverse=true的一方表示:“我是反向被控制的一方,我不负责维护关系”,而inverse=false则表示:"我是关系的控制方,拥有者,我会维护关系"。默认情况为inverse=false,即关系的两方都维护和控制关系,这种情况会造成一方重复一遍另一方已经完成的事情,比如更新外键列的值,这是不可取的,需要使用inverse=true来避免。
案例解释
1.类定义
Stock.java
StockDailyRecord.java
2. hibernate配置
Stock.hbm.xml
StockDailyRecord.hbm.xml
3. 问题
看如下文件 – “Stock.hbm.xml“.
如果修改Stock对象的stockDailyRecords变量,然后保存Stock对象,代码如下:
那么Hibernate会更新表StockDailyRecord的列“stock_daily_record.ITEM_ID”的值吗?
4. 答案
"inverse" 的值决定了上面的update语句会不会产生和执行
Inverse = false (如果不显示设置,默认值就是false) – 会执行更新(所以默认是会更新)
Inverse = true – 不会.
"Inverse = false" 例子
<!--Stock.hbm.xml-->
如果不显示设置inverse的值,inverse默认值就是false,那么上面的xml片段等价于如下片段
<!--Stock.hbm.xml-->
这意味着,关系的两方都是关系的拥有者。在Hibernate里,这会导致两方都会更新“StockDailyRecord”表的外键“stock_daily_record.ITEM_ID”的值:
如果Stock类的集合变量(stockDailyRecords)被修改了,Stock会更新外键“stock_daily_record.ITEM_ID”的值;
如果StockDailyRecord类的Stock变量被修改了,StockDailyRecord也会更新外键“stock_daily_record.ITEM_ID”的值;
1) Insert example
下面是当inverse=false时的保存新Stock对象的例子,Hibernate会产生2条SQL语句,一条insert,一条update
由于Stock是关系的拥有者(inverse=false),Stock会更新列“stock_daily_record.ITEM_ID”的值因为集合变量(stockDailyRecords)有修改
2) Update example
下面是当inverse=false时的update已经持久化过了的Stock对象的例子,Hibernate会产生3条SQL语句,一条insert,2条update
由于Stock是关系的拥有者(inverse=false),Stock会更新列“stock_daily_record.ITEM_ID”的值因为集合变量(stockDailyRecords)有修改
但是,第3条SQL语句是必须的,显而易见,第1条insert语句就已经为developer.stock_daily_record 保存了合适的STOCK_ID,所以第3条update语句是没有意义的,而且会损失性能。
通过设置inverse=true,我们可以阻止Hibernate产生第3条不必要的update语句
inverse = “true” 案例
<!--Stock.hbm.xml-->
集合变量stockDailyRecords上的inverse=true声明表示Stock不是关系的拥有者,关系由StockDailyRecord来维护。 在Hibernate里,这会阻止Stock更新外键“stock_daily_record.ITEM_ID”的值当集合变量(stockDailyRecords)被修改时。只有StockDailyRecord会更新“stock_daily_record.ITEM_ID”的值当StockDailyRecord的Stock属性被修改时。
1. Insert example
下面是当inverse=true时的保存新Stock对象的例子,Hibernate只会产生一条insert语句
由于Stock不是关系的拥有者,所以Stock不会更新表StockDailyRecord列“stock_daily_record.ITEM_ID”的值
2. Update example
Here’s an update example for inverse=”true”, Hibernate will generated two SQL statements, one insert and one update.
下面是当inverse=true时,Hibernate update已经持久化过了的Stock对象的例子,Hibernate会产生2条SQL语句,一条insert,1条update
由于Stock不是关系的拥有者,所以Stock不会更新表StockDailyRecord列“stock_daily_record.ITEM_ID”的值
结论
理解inverse的含义对于优化Hibernate的性能是至关重要的,正确的使用会避免Hibernate产生许多不必要的update语句。最后,记住inverse=true表示这一方不是关系的拥有者,不负责维护关系的更新。
参考文章
http://www.developer.am/documentation/hibernate/?page=inverse_true__explanation
关系(Relationship)由两方组成,其中被定义了inverse=true的一方表示:“我是反向被控制的一方,我不负责维护关系”,而inverse=false则表示:"我是关系的控制方,拥有者,我会维护关系"。默认情况为inverse=false,即关系的两方都维护和控制关系,这种情况会造成一方重复一遍另一方已经完成的事情,比如更新外键列的值,这是不可取的,需要使用inverse=true来避免。
案例解释
1.类定义
Stock.java
public class Stock implements java.io.Serializable ... private Set<StockDailyRecord> stockDailyRecords = new HashSet<StockDailyRecord>(0); ...
StockDailyRecord.java
public class StockDailyRecord implements java.io.Serializable ... private Stock stock; ...
2. hibernate配置
Stock.hbm.xml
<hibernate-mapping> <class name="com.developer.ammon.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock_daily_record" fetch="select"> <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.developer.ammon.StockDailyRecord" /> </set> ...
StockDailyRecord.hbm.xml
<hibernate-mapping> <class name="com.developer.ammon.StockDailyRecord" table="stock_daily_record" ...> ... <many-to-one name="stock" class="com.developer.ammon.Stock"> <column name="STOCK_ID" not-null="true" /> </many-to-one> ...
3. 问题
看如下文件 – “Stock.hbm.xml“.
<hibernate-mapping> <class name="com.developer.ammon.Stock" table="stock" ...> ... <set name="stockDailyRecords" table="stock_daily_record" fetch="select"> <key> <column name="STOCK_ID" not-null="true" /> </key> <one-to-many class="com.developer.ammon.StockDailyRecord" /> </set> ...
如果修改Stock对象的stockDailyRecords变量,然后保存Stock对象,代码如下:
Stock stock = new Stock(); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock);
那么Hibernate会更新表StockDailyRecord的列“stock_daily_record.ITEM_ID”的值吗?
Hibernate: update developer.stock_daily_record set STOCK_ID=? where DAILY_RECORD_ID=?
4. 答案
"inverse" 的值决定了上面的update语句会不会产生和执行
Inverse = false (如果不显示设置,默认值就是false) – 会执行更新(所以默认是会更新)
Inverse = true – 不会.
"Inverse = false" 例子
<!--Stock.hbm.xml-->
<set name="stockDailyRecords" table="stock_daily_record" ...>
如果不显示设置inverse的值,inverse默认值就是false,那么上面的xml片段等价于如下片段
<!--Stock.hbm.xml-->
<set name="stockDailyRecords" inverse="false" table="stock_daily_record" ...>
这意味着,关系的两方都是关系的拥有者。在Hibernate里,这会导致两方都会更新“StockDailyRecord”表的外键“stock_daily_record.ITEM_ID”的值:
如果Stock类的集合变量(stockDailyRecords)被修改了,Stock会更新外键“stock_daily_record.ITEM_ID”的值;
如果StockDailyRecord类的Stock变量被修改了,StockDailyRecord也会更新外键“stock_daily_record.ITEM_ID”的值;
1) Insert example
下面是当inverse=false时的保存新Stock对象的例子,Hibernate会产生2条SQL语句,一条insert,一条update
Stock stock = new Stock(); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); Output Hibernate: insert into developer.stock (STOCK_CODE, STOCK_NAME) values (?, ?) ... Hibernate: update developer.stock_daily_record set STOCK_ID=? where DAILY_RECORD_ID=?
由于Stock是关系的拥有者(inverse=false),Stock会更新列“stock_daily_record.ITEM_ID”的值因为集合变量(stockDailyRecords)有修改
2) Update example
下面是当inverse=false时的update已经持久化过了的Stock对象的例子,Hibernate会产生3条SQL语句,一条insert,2条update
Query q = session.createQuery("from Stock where stockCode = :stockCode "); q.setParameter("stockCode", "4715"); Stock stock = (Stock)q.list().get(0); stock.setStockName("GENM1"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); //set stockDailyRecords data stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); Output Hibernate: insert into developer.stock_daily_record (STOCK_ID, ...) values (?, ...) Hibernate: update developer.stock set STOCK_CODE=?, STOCK_NAME=? where STOCK_ID=? Hibernate: update developer.stock_daily_record set STOCK_ID=? where DAILY_RECORD_ID=?
由于Stock是关系的拥有者(inverse=false),Stock会更新列“stock_daily_record.ITEM_ID”的值因为集合变量(stockDailyRecords)有修改
但是,第3条SQL语句是必须的,显而易见,第1条insert语句就已经为developer.stock_daily_record 保存了合适的STOCK_ID,所以第3条update语句是没有意义的,而且会损失性能。
通过设置inverse=true,我们可以阻止Hibernate产生第3条不必要的update语句
inverse = “true” 案例
<!--Stock.hbm.xml-->
<set name="stockDailyRecords" inverse="true" table="stock_daily_record" ...>
集合变量stockDailyRecords上的inverse=true声明表示Stock不是关系的拥有者,关系由StockDailyRecord来维护。 在Hibernate里,这会阻止Stock更新外键“stock_daily_record.ITEM_ID”的值当集合变量(stockDailyRecords)被修改时。只有StockDailyRecord会更新“stock_daily_record.ITEM_ID”的值当StockDailyRecord的Stock属性被修改时。
1. Insert example
下面是当inverse=true时的保存新Stock对象的例子,Hibernate只会产生一条insert语句
Stock stock = new Stock(); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); Output Hibernate: insert into developer.stock (STOCK_CODE, STOCK_NAME) values (?, ?)
由于Stock不是关系的拥有者,所以Stock不会更新表StockDailyRecord列“stock_daily_record.ITEM_ID”的值
2. Update example
Here’s an update example for inverse=”true”, Hibernate will generated two SQL statements, one insert and one update.
下面是当inverse=true时,Hibernate update已经持久化过了的Stock对象的例子,Hibernate会产生2条SQL语句,一条insert,1条update
Query q = session.createQuery("from Stock where stockCode = :stockCode "); q.setParameter("stockCode", "4715"); Stock stock = (Stock)q.list().get(0); stock.setStockName("GENM1"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); //set stockDailyRecords data stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); Output Hibernate: insert into developer.stock_daily_record (STOCK_ID, ...) values (?, ...) Hibernate: update developer.stock set STOCK_CODE=?, STOCK_NAME=? where STOCK_ID=?
由于Stock不是关系的拥有者,所以Stock不会更新表StockDailyRecord列“stock_daily_record.ITEM_ID”的值
结论
理解inverse的含义对于优化Hibernate的性能是至关重要的,正确的使用会避免Hibernate产生许多不必要的update语句。最后,记住inverse=true表示这一方不是关系的拥有者,不负责维护关系的更新。
参考文章
http://www.developer.am/documentation/hibernate/?page=inverse_true__explanation
发表评论
-
Hibernate与 MyBatis的比较
2014-04-12 16:01 1315原文链接:http://blog.csdn ... -
用实例来解释inverse=true的含义
2013-09-25 18:18 2inverse=true含义: 关系(Relationship ... -
Hibernate中什么时候使用inverse=true
2013-09-25 16:45 4690准确理解inverse=true的含义 关系(Relation ... -
Hibernate中什么时候使用inverse=true
2013-09-25 16:33 5准确理解inverse=true的含义 关系(Relation ... -
hibernate中的inverse和mappedBy
2013-09-25 14:49 1683inverse和mappedBy是同一个东西,只是invers ... -
Hibernate学习笔记
2013-08-04 11:56 0Using Hibernate EntityManager H ... -
EJB3.0,JPA,Hibernate之间的关系
2013-07-28 12:47 22641.EJB3.0和JAP之间的关系 E ... -
OneToMany ManyToOne
2013-05-16 17:19 1013public class Perspective{ @One ... -
JoinColumn VS mappedBy
2013-05-16 17:13 2058What is the difference between: ... -
@PrimaryKeyJoinColumn and mappedBy
2013-05-16 16:58 39751 ANNOTATIONS 1.1 @PrimaryKeyJo ... -
[转]Hibernate 面试中最常考察的知识点整合
2013-03-29 10:48 1064Hibernate 面试中最常考察的知识点整合 http:// ... -
Hibernate学习笔记
2012-11-08 09:53 01)Hibernate中的components(组件)在JPA ... -
使用join fetch with JPA2 CriteriaQuery的简单例子
2012-01-18 15:45 9011protected TypedQuery<Searc ...
相关推荐
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库。在 Hibernate 中,级联操作(Cascade)和反向属性(Inverse)是管理对象关系的重要概念,特别是在处理一对多(One-to-...
本示例中,我们将使用两个表:`CUSTOMER`和`ORDERS`,来演示“一对多”关系。其中,`CUSTOMER`表包含客户的基本信息,如`id`、`name`和`age`等字段,而`ORDERS`表则存储了订单信息,包括`id`、`CUSTOMER_id`、`ORDER...
它允许开发人员使用面向对象的编程模型来操作数据库,而无需直接编写SQL语句。在这个实例中,我们将深入探讨Nhibernate在处理四种主要关系映射——一对一、一对多、多对一和多对多的关系映射。 ### 一对一关系...
<set name="roles" table="user_roles" inverse="true" lazy="true"> <key column="user_id" /> <many-to-many class="com.bean.manytomany.Role" column="role_id" /> ``` `Role.hbm.xml` 示例: ```xml ...
在上述配置中,我们可以使用 `lazy="true"` 参数来启用懒加载,例如: ```xml <one-to-many name="Employees" lazy="true"/> ``` 总结,NHibernate 通过配置文件或注解支持多种关系映射,包括一对一、一对多和多对...
在Java世界中,Hibernate是一个非常流行的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。本实例将详细讲解如何在Hibernate中实现Many-to-One关系映射,这是一种常见的...
然后,使用Hibernate的注解来声明这些关联,如`@OneToMany`和`@ManyToOne`。 在配置文件中,我们还需要为这个关联定义映射规则,包括fetch策略(选择是懒加载还是立即加载子项)、级联操作(如删除时是否一同删除...
在`<class>`标签内,通过`<set>`标签来定义这个集合,其中`name`属性是Java中的字段名,`table`属性指定数据库中的表名,`inverse="true"`表示这个关联的维护由`Order`端负责: ```xml <set name="orders" table=...
如果 Student 的 `inverse="true"`,那么添加一个新的 Student 时,Hibernate 不会在 TeacherStudent 表中插入新的记录。只有在处理 Teacher 时,Hibernate 才会更新中间表。 - 如果两端都是 `inverse="true"`,则...
在这个场景中,"一"端通常指的是一个实体可以拥有多个另一个实体的实例,而"多"端则相反,一个实体可以被多个另一个实体实例所拥有。在本例中,我们讨论的是`Student`(学生)和`Classes`(班级)的关系,一个班级...
<set name="addresses" table="address" lazy="true" inverse="true"> ``` #### 四、延迟加载的实例分析 假设我们有用户(User)和地址(Address)两个实体,一个用户可能有多个地址。如果我们没有使用延迟加载,...
<set name="computers" inverse="true" lazy="true" cascade="save-update"> <key column="p_id"/> <one-to-many class="Computer"/> <class name="Computer" table="Computer"> <id name="id"> ...
例如,在一对多关系中,如果`inverse`属性被设置为`true`,那么这一方将不会主动触发对关联实体的更新或删除操作,而是依赖于另一方实体来执行这些操作。这有助于避免并发修改异常,同时简化了代码的复杂度。 #### ...
<set name="courses" table="student_course" inverse="true" cascade="all"> <key column="student_id"/> <many-to-many column="course_id" class="com.example.Course"/> <!-- Course.hbm.xml --> ...
总结,本教程详细介绍了Hibernate中表关系的映射,包括不同关系的配置、`Cascade`和`Inverse`属性的使用,以及如何在Java类和XML配置文件中实现这些映射。理解并掌握这些概念对于高效使用Hibernate进行数据库操作至...
在`Classes`类的映射中,`<set>`标签表示一个班级可以包含多个学生,`inverse="true"`表明学生端维护班级关系,`cascade="all"`表示对集合中的每个实体执行级联操作。`<key>`定义了外键,`<one-to-many>`指定了与之...
总结来说,“IBaitsNet的对象关系一对多实现”涉及到的主要知识点包括:对象关系映射(ORM)、一对多关系、映射文件配置、集合属性的使用、外键和主键的概念、以及如何在代码中操作这些关系。通过理解并熟练运用这些...
"角色(使用hibernate映射多对多的关系).zip"这个压缩包文件提供了一个实例,展示了如何利用Hibernate来映射数据库中的多对多关联。在这个案例中,"角色"可能是一个典型的业务对象,它可能与多个其他实体有关系,...
- 多方设置`inverse=true`,即将主控权交给多方,这样多方可以主动从一方获取外键,然后一次`insert`即可完成。 #### 七、集合类型 - 支持`java.util.Set` 或 `net.sf.hibernate.collection.Bag` 类型的集合。 #...