Exemple de mise en veille prolongée (classe et collection)
En veille prolongée, «mutable» est défini par défaut sur «true» dans la classe et sa collection associée, cela signifie que la classe ou la collection est autorisée à ajouter, mettre à jour et supprimer. D'un autre côté, si le mutable est changé en false, il a une signification différente dans la classe et sa collection associée. Prenons quelques exemples pour en savoir plus.
Exemple d'hibernation un-à-plusieurs
Je prendrai cesone-to-many example pour la démonstration mutable. Dans ce fichier de mappage, un Stock appartient à de nombreux StockDailyRecord.
......
Comment déclarer mutable?
Le «mutable» est pris en charge à la fois dans le fichier de mappage XML et dans les annotations.
1. Fichier de mappage XML
Dans le fichier de mappage, le mot-clé ‘mutable’ est utilisé pour implémenter la fonction mutable.
......
2. Annotation
Dans l'annotation, le mot clé est changé en @Immutable (mutable = ’false’).
... @Entity @Immutable @Table(name = "stock", catalog = "example") public class Stock implements java.io.Serializable { ... @OneToMany(fetch = FetchType.LAZY, mappedBy = "stock") @Immutable public SetgetStockDailyRecords() { return this.stockDailyRecords; } ...
Mutable en classe
Si mutable = "false" ou @Immutable est déclaré dans l'élément de classe, cela signifie lesupdates to this class will be ignored, but no exception is thrown, only the add and delete operation are allow.
1. Insert de test
Stock stock = new Stock(); stock.setStockCode("7277"); stock.setStockName("DIALOG"); session.save(stock);
si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la classe.
Output
Hibernate: insert into example.stock (STOCK_CODE, STOCK_NAME) values (?, ?)
si mutable = «false» ou @Immutable est déclaré dans la classe.
Output
Hibernate: insert into example.stock (STOCK_CODE, STOCK_NAME) values (?, ?)
Mutable in class n’a aucun effet sur l’opération «insérer».
2. Mise à jour du test
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); stock.setStockName("DIALOG123"); session.saveOrUpdate(stock);
si mutable = "true" ou aucun @Immutable n'est déclaré dans la classe.
Output
Hibernate: select ...from example.stock stock0_ where stock0_.STOCK_CODE='7277' Hibernate: update example.stock set STOCK_CODE=?,STOCK_NAME=? where STOCK_ID=?
si mutable = «false» ou @Immutable est déclaré dans la classe.
Output
Hibernate: select ...from example.stock stock0_ where stock0_.STOCK_CODE='7277'
Mutable dans la classe ne permet pas à l'application de le mettre à jour, l'opération de «mise à jour» sera ignorée et aucune exception n'est levée
3. Test de suppression
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); session.delete(stock);
si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la classe.
Output
Hibernate: delete from example.stock where STOCK_ID=?
si mutable = «false» ou @Immutable est déclaré dans la classe.
Output
Hibernate: delete from example.stock where STOCK_ID=?
Mutable en classe n’a aucun effet sur l’opération de «suppression».
Mutable en collection
Si mutable = «false» ou @Immutable est déclaré dans la collection, cela signifie lesadd and delete-orphan are not allow in this collection, with exception throw, only update and ‘cascade delete all’ are allow.
1. Insert de test
Supposons que l'insertion en cascade est activée.
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); StockDailyRecord sdr = new StockDailyRecord(); sdr.setDate(new Date()); sdr.setStock(stock); stock.getStockDailyRecords().add(sdr); session.save(stock);
si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output
Hibernate: insert into example.stock_daily_record (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE) values (?, ?, ?, ?, ?, ?)
si mutable = «false» ou @Immutable est déclaré dans la collection.
Output
Exception in thread "main" org.hibernate.HibernateException: changed an immutable collection instance: [com.example.common.Stock.stockDailyRecords#111]
Mutable dans la collection n’autorise pas l’opération «ajouter», une exception sera levée.
2. Mise à jour du test
Supposons que la mise à jour en cascade soit activée.
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next(); sdr.setPriceChange(new Float(1.30)); session.saveOrUpdate(stock);
si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output
Hibernate: update example.stock_daily_record set PRICE_CHANGE=?, ... where DAILY_RECORD_ID=?
si mutable = «false» ou @Immutable est déclaré dans la collection.
Output
Hibernate: update example.stock_daily_record set PRICE_CHANGE=?, ... where DAILY_RECORD_ID=?
Mutable dans la collection n’a aucun effet sur l’opération de «mise à jour».
3. Test de suppression-orphelin
Supposons que lecascade delete-orphan est activé.
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); StockDailyRecord sdr = stock.getStockDailyRecords().iterator().next(); stock.getStockDailyRecords().remove(sdr); session.saveOrUpdate(stock);
si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output
Hibernate: delete from example.stock_daily_record where DAILY_RECORD_ID=?
si mutable = «false» ou @Immutable est déclaré dans la collection.
Output
Exception in thread "main" org.hibernate.HibernateException: changed an immutable collection instance: [com.example.common.Stock.stockDailyRecords#111]
Mutable dans la collection n’autorise pas l’opération ‘delete-orphan’, une exception sera levée.
4. Test de suppression
Supposons que la suppression en cascade est activée.
Stock stock = (Stock)session.createQuery( " from Stock where stockCode = '7277'").list().get(0); session.saveOrUpdate(stock);
si mutable = «true» (par défaut) ou aucun @Immutable n'est déclaré dans la collection.
Output
Hibernate: delete from example.stock_daily_record where DAILY_RECORD_ID=? Hibernate: delete from example.stock where STOCK_ID=?
si mutable = «false» ou @Immutable est déclaré dans la collection.
Output
Hibernate: delete from example.stock_daily_record where DAILY_RECORD_ID=? Hibernate: delete from example.stock where STOCK_ID=?
Mutable dans la collection n’a aucun effet sur l’opération de «suppression», si le parent est supprimé, tout son enfant sera également supprimé, même s'il est modifiable.
Pourquoi mutable?
Mutable peut éviter de nombreuses opérations de base de données involontaires, comme ajouter, mettre à jour ou supprimer certains enregistrements qui ne devraient pas l'être. De plus, selon la documentation Hibernate, le do mutable a quelques optimisations de performances mineures, il est toujours recommandé d'analyser votre relation de mappage et d'implémenter le mutable selon les besoins.
Sommaire
1. mutable = "false" ou @Immutable est déclaré en classe
cela signifie que les mises à jour de cette classe seront ignorées, mais aucune exception n'est levée, seules les opérations d'ajout et de suppression sont autorisées.
En classe avec mutable = "false" - insert = allow, delete = allow, update = not allow
2. mutable = "false" ou @Immutable est déclaré dans la collection
cela signifie que les ajouts et les suppressions d'orphelins ne sont pas autorisés dans cette collection, à l'exception du lancer, seule la mise à jour est autorisée. Cependant, si la suppression en cascade est activée, lorsque le parent est supprimé, tout son enfant sera également supprimé, même s'il est modifiable.
Dans la collection avec mutable = "false" - insert = not allow, delete-orphan = not allow, delete = allow, update = allow
Complètement immuable?
Une classe peut-elle complètement immuable à des actions? Oui, mettez un mutable = "faux" à toute sa relation (insert = pas autorisé, delete-orphan = pas autorisé), et un mutable = "faux" à la classe que vous voulez immuable (update = pas autoriser). Maintenant, vous avez une classe complètement immuable, cependant, si l'option de suppression en cascade est activée, lorsque le parent de votre classe immuable est supprimé, votre classe immuable sera également supprimée.