Hibernate - カスケードの例(保存、更新、削除、削除 - 孤立)

Hibernate –カスケードの例(保存、更新、削除、削除オーファン)

カスケードは、反対側の状態を手動で管理するために必要なコード行を保存する便利な機能です。

コレクションの状態を自動的に管理するために、「マッピング」キーワードがコレクションマッピングに表示されることがよくあります。 このチュートリアルでは、このone-to-many exampleを使用してカスケード効果を示します。

カスケード保存/更新の例

この例では、「Stock」が保存されている場合、参照されているすべての「stockDailyRecords」もデータベースに保存する必要があります。

1. 更新の保存カスケードなし

previous sectionで、「Stock」とその参照される「StockDailyRecord」をデータベースに保存する場合は、両方を個別に保存する必要があります。

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

出力

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. 更新保存カスケード

cascade=”save-update”は、「stockDailyRecords」で宣言され、保存と更新のカスケード効果を有効にします。


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

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

session.save(stock);

出力

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 (?, ?, ?, ?, ?, ?)

コードsession.save(stockDailyRecords);は不要になりました。「Stock」を保存すると、参照されている「stockDailyRecords」に保存操作が「カスケード」され、両方がデータベースに自動的に保存されます。

カスケード削除の例

この例では、「Stock」が削除された場合、参照されている「stockDailyRecords」もすべてデータベースから削除する必要があります。

1. 削除カスケードなし

すべての「stockDailyRecords」をループして、1つずつ削除する必要があります。

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

出力

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

2. カスケード削除

cascade=”delete”は、カスケード削除効果を有効にするために「stockDailyRecords」で宣言されています。 「Stock」を削除すると、その参照「stockDailyRecords」はすべて自動的に削除されます。


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

出力

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

カスケード削除オーファンの例

上記のカスケード削除オプションでは、Stockを削除すると、その参照されているすべての「stockDailyRecords」もデータベースから削除されます。 参照されている2つの「stockDailyRecords」レコードだけを削除する場合はどうでしょうか。 これは孤立した削除と呼ばれます。例を参照してください…

1. 削除オーファンカスケードなし

「stockDailyRecords」を1つずつ削除する必要があります。

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

出力

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

2. 孤立したカスケードの削除

cascade=”delete-orphan”は、「stockDailyRecords」で宣言され、孤立したカスケードの削除効果を有効にします。 ストックを保存または更新すると、既に削除済みとしてマークされている「stockDailyRecords」が削除されます。


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

出力

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

要するに、delete-orphanを使用すると、親テーブルは子テーブル内のいくつかのレコードを削除(孤立した削除)できます。

カスケードを有効にする方法は?

カスケードは、XMLマッピングファイルと注釈の両方でサポートされています。

1. XMLマッピングファイル

XMLマッピングファイルで、関係変数でcascadeキーワードを宣言しました。


      
            
      
      

2. アノテーション

アノテーションで、@ CascadeアノテーションでCascadeType.SAVE_UPDATE(保存、更新)とCascadeType.REMOVE(削除)を宣言しました。

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

逆対カスケード

どちらもまったく異なる概念です。differential hereを参照してください。

結論

カスケードは、相手側の状態を自動的に管理するための非常に便利な機能です。 ただし、この機能には価格があります。賢く使用しないと(更新または削除)、パフォーマンスを低下させるために多くの不要なカスケード効果(カスケード更新)が生成されたり、使用しなかったデータを削除(カスケード削除)したりします期待した。