Hibernate - Exemple en cascade (sauvegarde, mise à jour, suppression et suppression orpheline)

Hibernate - Exemple en cascade (enregistrer, mettre à jour, supprimer et supprimer-orphelin)

La cascade est une fonctionnalité pratique pour enregistrer les lignes de code nécessaires pour gérer manuellement l'état de l'autre côté.

Le mot-clé «Cascade» apparaît souvent sur le mappage de collection pour gérer automatiquement l'état de la collection. Dans ce didacticiel, ceone-to-many example sera utilisé pour démontrer l'effet de cascade.

Exemple de sauvegarde / mise à jour en cascade

Dans cet exemple, si un «Stock» est enregistré, tous ses «stockDailyRecords» référencés doivent également être enregistrés dans la base de données.

1. Pas de cascade de sauvegarde-mise à jour

Dansprevious section, si vous souhaitez enregistrer le "Stock" et son "StockDailyRecord" référencé dans la base de données, vous devez enregistrer les deux individuellement.

Stock stock = new Stock();
StockDailyRecord stockDailyRecords = new StockDailyRecord();
//set the stock and stockDailyRecords  data

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);
session.save(stockDailyRecords);

Sortie

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

Hibernate:
    insert into example.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

2. Avec cascade de mise à jour de sauvegarde

Lecascade=”save-update” est déclaré dans «stockDailyRecords» pour activer l’effet de cascade sauvegarde-mise à jour.



      
            
      
      
Stock stock = new Stock();
StockDailyRecord stockDailyRecords = new StockDailyRecord();
//set the stock and stockDailyRecords  data

stockDailyRecords.setStock(stock);
stock.getStockDailyRecords().add(stockDailyRecords);

session.save(stock);

Sortie

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

Hibernate:
    insert into example.stock_daily_record
    (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

Le codesession.save(stockDailyRecords); n’est plus nécessaire, lorsque vous enregistrez le «Stock», il «cascade» l’opération de sauvegarde sur celui-ci référencé «stockDailyRecords» et enregistre automatiquement les deux dans la base de données.

Exemple de suppression en cascade

Dans cet exemple, si un «Stock» est supprimé, tous ses «stockDailyRecords» référencés doivent également être supprimés de la base de données.

1. Pas de cascade de suppression

Vous devez boucler tous les ‘stockDailyRecords’ et les supprimer un par un.

Query q = session.createQuery("from Stock where stockCode = :stockCode ");
q.setParameter("stockCode", "4715");
Stock stock = (Stock)q.list().get(0);

for (StockDailyRecord sdr : stock.getStockDailyRecords()){
         session.delete(sdr);
}
 session.delete(stock);

Sortie

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

2. Avec suppression en cascade

Lecascade=”delete” est déclaré dans «stockDailyRecords» pour activer l’effet de suppression en cascade. Lorsque vous supprimez le "Stock", toutes ses références "stockDailyRecords" seront supprimées automatiquement.



      
            
      
      
Query q = session.createQuery("from Stock where stockCode = :stockCode ");
q.setParameter("stockCode", "4715");
Stock stock = (Stock)q.list().get(0);
session.delete(stock);

Sortie

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

Exemple de suppression-orphelin en cascade

Dans l'option de suppression en cascade ci-dessus, si vous supprimez un stock, tous ses «stockDailyRecords» référencés seront également supprimés de la base de données. Que diriez-vous si vous souhaitez simplement supprimer deux enregistrements référencés «stockDailyRecords»? Cela s'appelle la suppression orpheline, voir l'exemple…

1. Pas de cascade suppression-orphelin

Vous devez supprimer les ‘stockDailyRecords’ un par un.

StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                            new Integer(56));
StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                            new Integer(57));

session.delete(sdr1);
session.delete(sdr2);

Sortie

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?
Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

2. Avec cascade suppression-orphelin

Lecascade=”delete-orphan” est déclaré dans «stockDailyRecords» pour activer l’effet de suppression en cascade des orphelins. Lorsque vous enregistrez ou mettez à jour le stock, il supprimera les «stockDailyRecords» qui marquent déjà comme supprimés.



      
            
      
      
StockDailyRecord sdr1 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                       new Integer(56));
StockDailyRecord sdr2 = (StockDailyRecord)session.get(StockDailyRecord.class,
                                       new Integer(57));

Stock stock = (Stock)session.get(Stock.class, new Integer(2));
stock.getStockDailyRecords().remove(sdr1);
stock.getStockDailyRecords().remove(sdr2);

session.saveOrUpdate(stock);

Sortie

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?
Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

En bref, delete-orphan permet à la table parent de supprimer quelques enregistrements (supprimer orphelin) dans sa table enfant.

Comment activer la cascade?

La cascade est prise en charge à la fois dans le fichier de mappage XML et dans les annotations.

1. Fichier de mappage XML

Dans le fichier de mappage XML, déclarez le mot clécascade dans votre variable de relation.



      
            
      
      

2. Annotation

Dans l'annotation, a déclaré lesCascadeType.SAVE_UPDATE (enregistrer, mettre à jour) etCascadeType.REMOVE (supprimer) dans l'annotation @Cascade.

        //Stock.java
        @OneToMany(mappedBy = "stock")
        @Cascade({CascadeType.SAVE_UPDATE, CascadeType.DELETE})
    public Set getStockDailyRecords() {
        return this.stockDailyRecords;
    }

inverse vs cascade

Les deux sont des notions totalement différentes, voir lesdifferential here.

Conclusion

La cascade est une fonction très pratique pour gérer automatiquement l'état de l'autre côté. Cependant, cette fonctionnalité a un prix.Si vous ne l'utilisez pas judicieusement (mise à jour ou suppression), elle générera de nombreux effets de cascade inutiles (mise à jour en cascade) pour ralentir vos performances, ou supprimera (suppression en cascade) certaines données que vous n'avez pas attendu.