inverse = "vrai" exemple et explication
Always put inverse=”true” in your collection variable ?
Il existe de nombreux articles d'Hibernate qui tentent d'expliquer «l'inverse» avec de nombreux jargon «officiel» d'Hibernate, ce qui est très difficile à comprendre (du moins pour moi). Dans quelques articles, ils ont même suggéré d'oublier simplement ce qui est «inverse» et de toujours mettreinverse=”true” dans la variable de collection.
Cette affirmation est toujours vraie - «mettez inverse = true dans la variable de collection», mais ne lui bandez pas les yeux, essayez de comprendre la raison derrière est essentielle pour optimiser vos performances Hibernate.
Qu'est-ce que «l'inverse»?
C'est le mot-clé le plus déroutant dans Hibernate, au moins j'ai mis beaucoup de temps à le comprendre. Le mot-clé «inverse» est toujours déclaré dans la relationone-to-many etmany-to-many (plusieurs-à-un n'a pas de mot-clé inverse), cela signifie quel côté est chargé de prendre en charge le relation.
«Inverse», devrait devenir «propriétaire de la relation»?
Dans Hibernate, seul le «propriétaire de la relation» doit maintenir la relation, et le mot clé «inverse» est créé pour définir de quel côté le propriétaire doit maintenir la relation. Cependant, le mot-clé «inverse» lui-même n'est pas assez détaillé, je suggérerais de le changer en «relationship_owner».
En bref, inverse = "true" signifie que c'est le propriétaire de la relation, et inverse = "false" (par défaut) signifie que ce n'est pas le cas.
1. Relation un à plusieurs
Il s'agit d'une conception de table de relationsone-to-many, une table STOCK a de nombreuses occurrences dans la table STOCK_DAILY_RECORD.
2. Mise en œuvre d'Hibernate
Voir l'implémentation Hibernate dans les fichiers de mappage XML.
Fichier: Stock.java
public class Stock implements java.io.Serializable { ... private SetstockDailyRecords = new HashSet (0); ...
Fichier: StockDailyRecord.java
public class StockDailyRecord implements java.io.Serializable { ... private Stock stock; ...
Fichier: Stock.hbm.xml
... ...
Fichier: StockDailyRecord.hbm.xml
... ...
3. inverse = vrai / faux
Le mot clé inverse est appliqué dans une relation un à plusieurs. Voici la question, si l'opération d'enregistrement ou de mise à jour s'effectue dans l'objet "Stock", doit-elle mettre à jour la relation "stockDailyRecords"?
Fichier: Stock.hbm.xml
... ...
1. inverse = "vrai"
Si inverse = "true" dans la variable définie, cela signifie que "stock_daily_record" est le propriétaire de la relation, donc Stock ne mettra PAS à jour la relation.
...
2. inverse = "faux"
Si inverse = "false" (par défaut) dans la variable définie, cela signifie que "stock" est le propriétaire de la relation, et Stock mettra à jour la relation.
...
Voir plus d'exemples ci-dessous:
4. inverse = "false" Exemple
Si le mot clé "inverse" n'est pas défini, l'inverse = "false" sera utilisé, ce qui est
...
Cela signifie que «stock» est le propriétaire de la relation, et il maintiendra la relation.
Insérer un exemple…
Lorsqu'un objet «Stock» est enregistré, Hibernate génère trois instructions SQL, deux insertions et une mise à jour.
session.beginTransaction(); Stock stock = new Stock(); stock.setStockCode("7052"); stock.setStockName("PADINI"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.save(stockDailyRecords); session.getTransaction().commit();
Production…
Hibernate: insert into exampledb.stock (STOCK_CODE, STOCK_NAME) values (?, ?) Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?) Hibernate: update exampledb.stock_daily_record set STOCK_ID=? where RECORD_ID=?
Stock mettra à jour les «stock_daily_record.STOCK_ID» via la variable Set (stockDailyRecords), car Stock est le propriétaire de la relation.
Note
La troisième instruction n'est vraiment PAS nécessaire.
Exemple de mise à jour…
Lorsqu'un objet «Stock» est mis à jour, Hibernate génère deux instructions SQL, une insérée et une mise à jour.
session.beginTransaction(); Stock stock = (Stock)session.get(Stock.class, 57); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); session.getTransaction().commit();
Production…
Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?) Hibernate: update exampledb.stock_daily_record set STOCK_ID=? where RECORD_ID=?
Note
Encore une fois, la troisième instruction n'est PAS nécessaire.
5. inverse = "true" Exemple
Si le mot clé "inverse = true" est défini:
...
Maintenant, cela signifie que «stockDailyRecords» est le propriétaire de la relation, et «stock» ne maintiendra pas la relation.
Insérer un exemple…
Lorsqu'un objet «Stock» est enregistré, Hibernate génère deux instructions d'insertion SQL.
session.beginTransaction(); Stock stock = new Stock(); stock.setStockCode("7052"); stock.setStockName("PADINI"); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stock); session.save(stockDailyRecords); session.getTransaction().commit();
Production …
Hibernate: insert into exampledb.stock (STOCK_CODE, STOCK_NAME) values (?, ?) Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
Exemple de mise à jour…
Lorsqu'un objet «Stock» est mis à jour, Hibernate génère une instruction SQL.
session.beginTransaction(); Stock stock = (Stock)session.get(Stock.class, 57); StockDailyRecord stockDailyRecords = new StockDailyRecord(); stockDailyRecords.setPriceOpen(new Float("1.2")); stockDailyRecords.setPriceClose(new Float("1.1")); stockDailyRecords.setPriceChange(new Float("10.0")); stockDailyRecords.setVolume(3000000L); stockDailyRecords.setDate(new Date()); stockDailyRecords.setStock(stock); stock.getStockDailyRecords().add(stockDailyRecords); session.save(stockDailyRecords); session.update(stock); session.getTransaction().commit();
Production…
Hibernate: insert into exampledb.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
inverse vs cascade
Beaucoup de gens aiment comparer l'inverse et la cascade, mais les deux sont des notions totalement différentes, voir lesdifferential here.
Conclusion
Comprendre l '«inverse» est essentiel pour optimiser votre code Hibernate, il permet d'éviter de nombreuses instructions de mise à jour inutiles, comme «exemple d'insertion et de mise à jour pour inverse = false» ci-dessus. Enfin, essayez de vous rappeler l'inverse = "vrai" signifie que c'est le propriétaire de la relation qui gère la relation.