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
StockDailyRecord.java
Stock.hbm.xml
StockDailyRecord.hbm.xml
3. Question …
See this file – “Stock.hbm.xml“.If the Set variable (stockDailyRecords) in Stock object is modified, and save the Stock object like followingWill it update the StockDailyRecord table?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 toIt 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 SQLSta, one insert and one update.OutputStock 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.OutputStock 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 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.OutputSince “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.OutputSince “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 differencial 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
- http://www.mkyong.com/hibernate/inverse-true-example-and-explanation/
- http://simoes.org/docs/hibernate-2.1/155.html
- http://docs.jboss.org/hibernate/stable/core/reference/en/html/example-parentchild.html
- http://tadtech.blogspot.com/2007/02/hibernate-when-is-inversetrue-and-when.html
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
StockDailyRecord.java
Stock.hbm.xml
StockDailyRecord.hbm.xml
3. Question …
See this file – “Stock.hbm.xml“.
If the Set variable (stockDailyRecords) in Stock object is modified, and save the Stock object like following
Will it update the StockDailyRecord table?
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
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 SQLSta, one insert and one update.
Output
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.
Output
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.
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 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.
Output
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.
Output
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 differencial here.
Many people like to compare between inverse and cascade, but both are totally different notions, see the differencial 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
- http://www.mkyong.com/hibernate/inverse-true-example-and-explanation/
- http://simoes.org/docs/hibernate-2.1/155.html
- http://docs.jboss.org/hibernate/stable/core/reference/en/html/example-parentchild.html
- http://tadtech.blogspot.com/2007/02/hibernate-when-is-inversetrue-and-when.html
No comments:
Post a Comment