inverse = “true” example and explanation

Written on January 31, 2010 at 4:19 pm by mkyong | Under Hibernate category

What is “inverse”?

This is the most confusing keyword in Hibernate, at least i took quite a long time to understand what is it. The “inverse” keyword is always declared in one-to-many and many-to-many relationship (many-to-one doesn’t has inverse keyword), It defines which side is responsible to take care of the relationship.

Always put inverse=”true” in your collection variable?

There are many Hibernate articles try to explain the “inverse” with many Hibernate “official” jargon, which is very hard to understand (at least to me). In few articles, they even suggested that just forget about what is “inverse”, and always put the inverse=”true” in the collection variable. This statement is always true – “put inverse=true in collection variable”, but do not blindfold on it, try to understand the reason behind is essential to optimal your Hibernate performance.

“inverse”, can it change to “relationship owner”?

In Hibernate, only the relationship owner should maintain the relationship, and the “inverse” keyword is created to defines which side is the owner to maintain the relationship. However the “inverse” keyword itself is not verbose enough, I would suggest change the keyword to “relationship_owner“. The inverse=”true” means this is the relationship owner, whereas inverse=”false” (default) means it’s not.

Let’s go though a quick example to grab a draft idea of “inverse”…

Preparing the data for demonstration…

1. Database tables

This is a one-to-many relationship table design, a STOCK table has many occurrences in STOCK_DAILY_RECORD table.

2. Hibernate implementation

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;   ...

Stock.hbm.xml
<hibernate-mapping>

<class name="com.mkyong.common.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.mkyong.common.StockDailyRecord" />

</set>    ...

StockDailyRecord.hbm.xml
<hibernate-mapping>

<class name="com.mkyong.common.StockDailyRecord" table="stock_daily_record" ...>

  ...<many-to-one name="stock" class="com.mkyong.common.Stock">

<column name="STOCK_ID" not-null="true" />

</many-to-one>  ...

3. Question …

See this file – “Stock.hbm.xml“.

<hibernate-mapping>

<class name="com.mkyong.common.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.mkyong.common.StockDailyRecord" />

</set>    ...

If the Set variable (stockDailyRecords) in Stock object is modified, and save the Stock object like following

Stock stock = new Stock();

stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);

Will it update the StockDailyRecord table?

Hibernate:     update mkyong.stock_daily_record set STOCK_ID=? 

    where DAILY_RECORD_ID=?

4. Answer …

inverse” is controlling the above scenario, to define which side should maintain the relationship.

  • Inverse = false (default) – will execute “update mkyong.stock_daily_record” and update the relationship.
  • Inverse = true – Do nothing.

Got it? May be not, let’s explore more examples to understand about it.

“Inverse = false” example

If no “inverse” keyword is declared, the default is inverse = “false”, which is equal to

<!--Stock.hbm.xml-->...<set name="stockDailyRecords" inverse="false" table="stock_daily_record" ...>

It means both sides are the owner of the relationship. In Hibernate, it will ask both sides to update the foreign key “stock_daily_record.STOCK_ID” in “StockDailyRecord” table.

  • Stock will update the foreign key “stock_daily_record.STOCK_ID” if Set variable (stockDailyRecords) is modified.
  • StockDailyRecord will update the foreign key “stock_daily_record.STOCK_ID” with Stock property as well.

1. Insert example …

Here’s an insert example for inverse=”false”, when a Stock object is saved, Hibernate will generated two SQL statements, one insert and one update.

Stock stock = new Stock();

stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);

Output

Hibernate:     insert into mkyong.stock (STOCK_CODE, STOCK_NAME)     values (?, ?)...Hibernate:     update mkyong.stock_daily_record 

    set STOCK_ID=?     where DAILY_RECORD_ID=?

Stock will update the “stock_daily_record.STOCK_ID” through Set variable (stockDailyRecords), because Stock is the relationship owner.

2. Update example …

Here’s an update example for inverse=”false”, Hibernate will generated three SQL statements, one insert and two updates.

        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 mkyong.stock_daily_record (STOCK_ID, ...) 

    values (?, ...)

Hibernate:     update mkyong.stock set STOCK_CODE=?, STOCK_NAME=? 

    where STOCK_ID=?

Hibernate:     update mkyong.stock_daily_record set STOCK_ID=? 

    where DAILY_RECORD_ID=?

Stock will update the “stock_daily_record.STOCK_ID” through Set variable (stockDailyRecords), because Stock is the relationship owner.

Note
Wait…do you think the third update statement is necessary? The inverse = “true” in Set variable (stockDailyRecords) can stop the Hibernate to generate the unnecessary third update statement.

inverse = “true” example

The inverse=”true” is declared at the Set variable (stockDailyRecords), which means Stock is not the relationship owner, the owner is belong to StockDailyRecord class. In Hibernate, it will enable only the StockDailyRecord class to update the foreign key “stock_daily_record.STOCK_ID” in StockDailyRecord table.

<!--Stock.hbm.xml--><set name="stockDailyRecords" inverse="true" table="stock_daily_record" ...>

  • Stock will not update the foreign key “stock_daily_record.STOCK_ID” if Set variable (stockDailyRecords) is modified.
  • Only StockDailyRecord will update the foreign key “stock_daily_record.STOCK_ID” with Stock property.

1. Insert example …

Here’s an insert example for inverse=”true”, when a Stock object is saved, Hibernate will generated one insert SQL statement.

Stock stock = new Stock();

stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);

Output

Hibernate:     insert into mkyong.stock (STOCK_CODE, STOCK_NAME)     values (?, ?)

Since “Stock” is not the owner of the relationship, it will not update the “stock_daily_record.STOCK_ID” in StockDailyRecord table.

2. Update example …

Here’s an update example for inverse=”true”, Hibernate will generated two SQL statements, one insert and one 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 mkyong.stock_daily_record (STOCK_ID, ...) 

    values (?, ...)

Hibernate:     update mkyong.stock set STOCK_CODE=?, STOCK_NAME=? 

    where STOCK_ID=?

Since “Stock” is not the owner of the relationship, it will not update the “stock_daily_record.STOCK_ID” in stockDailyRecord table.

inverse vs cascade
Many people like to compare between inverse and cascade, but both are totally different notions, see the differential here.

Conclusion

Understanding the “inverse” is essential to optimize your Hibernate code, it helps to avoid many unnecessary update statements, which mention in the “update example for inverse=false” above. At last, try to remember the inverse=”true” mean this is the relationship owner to handle the relationship.

Reference

  1. http://simoes.org/docs/hibernate-2.1/155.html
  2. http://docs.jboss.org/hibernate/stable/core/reference/en/html/example-parentchild.html
  3. http://tadtech.blogspot.com/2007/02/hibernate-when-is-inversetrue-and-when.html

转载于:https://www.cnblogs.com/wenjielee/archive/2010/12/29/1920463.html

转:inverse = “true” example and explanation相关推荐

  1. 关于Hibernate中inverse=true的转载

    1.到底在哪用cascade="..."? cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所 ...

  2. 06章 映射一对多双向关联关系、以及cascade、inverse属性

    当类与类之间建立了关联,就可以方便的从一个对象导航到另一个对象.或者通过集合导航到一组对象.例如: 对于给定的Emp对象,如果想获得与它关联的Dept对象,只要调用如下方法 Dept dept=emp ...

  3. hibernate中inverse作用

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

  4. cascade inverse (2010-01-12)

    1.到底在哪用cascade="..."?       cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入 ...

  5. java之hibernate之 cascade和inverse

    1.Cascade是级联动作,在many_to_one中如果使用cascade可以级联操作关联对象,如下代码可以级联保存Category对象. 在Book的映射文件设置 <many-to-one ...

  6. Hibernate关键字inverse和cascade

    2019独角兽企业重金招聘Python工程师标准>>> 维护关联关系中,是否设置inverse属性: 1. 保存数据                  有影响. 如果设置控制反转,即 ...

  7. hibernate的inverse用法

    Inverse和cascade是Hibernate映射中最难掌握的两个属性.两者都在对象的关联操作中发挥作用. 1.明确inverse和cascade的作用 inverse 决定是否把对对象中集合的改 ...

  8. inverse和Cascade详解

    Hibernate中的inverse在表关系映射中经常应用, inverse的值有两种,"true"和"false".inverse="false&q ...

  9. Hibernate中Inverse和Cascade

    Inverse和cascade是Hibernate映射中最难掌握的两个属性.两者都在对象的关联操作中发挥作用. 1.inverse属性:inverse所描述的是对象之间关联关系的维护方式. inver ...

最新文章

  1. “智享未来 知行合一”,开为科技AI产品发布会于2月6日召开
  2. 学习Kotlin(六)扩展与委托
  3. 代理(Proxy)模式
  4. python课程的中期报告_电子课程设计中期报告
  5. [CQOI2015]选数(杜教筛)
  6. 公司绝不会告诉你的20大秘密
  7. linux下的C语言开发(线程等待)
  8. java opencv去除干扰线_电子产品硬件研发—提高抗干扰性能的常用方法
  9. 安卓导航车机root方法_手机、平板这么好用,为什么车机还这么垃圾
  10. java中日期转换_java中日期格式的转换
  11. 微信小程序: 摇色子
  12. mysql打字竖线_如何打出竖线,教你怎样键盘打出竖线?
  13. 阿里华为腾讯美的全套人力资源管理资料合集(员工手册+员工关系及胜任能力+人事常用图表+岗位面试、说明+人才梯队建设),共2170份,1G
  14. 从k8s.gcr.io拉取镜像
  15. Linux系统定时任务crond那些事
  16. 仿微信群聊头像(图像合成、缩放)
  17. 设计商品分类表 mysql_商品分类表设计
  18. 计算机动画设计与影视制作,计算机动画设计及制作中的特效技术
  19. 【设计模式】牛市股票还会亏钱 --- 外观模式
  20. GaussDB数据库基础函数介绍-上

热门文章

  1. 华为P8正式发布 售价分别为549欧元和649欧元
  2. java agent内存马学习
  3. 从1G到5G,46年屏幕变迁下,富士康、苹果、三星、华为的浴火重生路...
  4. QLabel设置字体大小和内容
  5. NBA表格_爬取NBA球员薪资数据【Python数据分析百例连载】
  6. MongoDB的安装和启动
  7. JAVA增删改查代码
  8. 苹果应用雷达提供对苹果App Store排名的宏观分析服务
  9. oracle 中累加函数,CSS_oracle使用sum函数进行累加计算,====================Question============ - phpStudy...
  10. Word2010 如何解决文本框中的图片不能设置文字环绕的终极方法!!!