- 浏览: 781398 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (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 1248原文链接:http://blog.csdn ... -
用实例来解释inverse=true的含义
2013-09-25 18:18 2inverse=true含义: 关系(Relationship ... -
Hibernate中什么时候使用inverse=true
2013-09-25 16:45 4613准确理解inverse=true的含义 关系(Relation ... -
Hibernate中什么时候使用inverse=true
2013-09-25 16:33 5准确理解inverse=true的含义 关系(Relation ... -
hibernate中的inverse和mappedBy
2013-09-25 14:49 1629inverse和mappedBy是同一个东西,只是invers ... -
Hibernate学习笔记
2013-08-04 11:56 0Using Hibernate EntityManager H ... -
EJB3.0,JPA,Hibernate之间的关系
2013-07-28 12:47 22111.EJB3.0和JAP之间的关系 E ... -
OneToMany ManyToOne
2013-05-16 17:19 956public class Perspective{ @One ... -
JoinColumn VS mappedBy
2013-05-16 17:13 2012What is the difference between: ... -
@PrimaryKeyJoinColumn and mappedBy
2013-05-16 16:58 39131 ANNOTATIONS 1.1 @PrimaryKeyJo ... -
[转]Hibernate 面试中最常考察的知识点整合
2013-03-29 10:48 1011Hibernate 面试中最常考察的知识点整合 http:// ... -
Hibernate学习笔记
2012-11-08 09:53 01)Hibernate中的components(组件)在JPA ... -
使用join fetch with JPA2 CriteriaQuery的简单例子
2012-01-18 15:45 8951protected TypedQuery<Searc ...
相关推荐
4 参考数据,指的是供应用参考的常量数据,它的实例数目有限,它的实例会被许多其他类的实例引用,实例极少或者从来不会被修改。 2.3.3. 不适合存放到第二级缓存的数据? 1 经常被修改的数据 2 财务数据,绝对不允许...
整个层次结构中的所有父类和子类属性都映射到同一个表中,他们的实例通过一个辨别符列(discriminator)来区分。 Plane 是父类。@DiscriminatorColumn 注解定义了辨别符列。对于继承层次结构中的每个类, @...
many-to-one:标签中对于cascade的取值delete,delete-orphan,all-delete-orphan(只用unique属性值不为true不能出现)慎用 cascade:级联属性 none:不做任何级联操作 save-update:对当前对象执行save,update, ...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中有...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 71、说出一些常用的类,包,接口,请各举5个 72、java中有几种...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中有...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中有...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中有...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中有...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 52 71、说出一些常用的类,包,接口,请各举5个 54 72、java中有...
70、TreeSet里面放对象,如果同时放入了父类和子类的实例对象,那比较时使用的是父类的compareTo方法,还是使用的子类的compareTo方法,还是抛异常! 48 71、说出一些常用的类,包,接口,请各举5个 49 72、java中有...
10、使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变? .................................................................................................................................