Cascade is a convenient feature to save the lines of code needed to
manage the state of the other side manually.

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

カスケードセーブ/アップデートの例

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

1.セーブアップデートカスケードなし

リンク://hibernate/hibernate-one-to-many-relationship-example/[前のセクション]では、 ‘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 mkyong.stock (STOCK__CODE, STOCK__NAME)
    values (?, ?)

Hibernate:
    insert into mkyong.stock__daily__record
    (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

2. save-updateカスケードで

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="save-update" table="stock__daily__record"...>
      <key>
            <column name="STOCK__ID" not-null="true"/>
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord"/>
</set>

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 mkyong.stock (STOCK__CODE, STOCK__NAME)
    values (?, ?)

Hibernate:
    insert into mkyong.stock__daily__record
    (STOCK__ID, PRICE__OPEN, PRICE__CLOSE, PRICE__CHANGE, VOLUME, DATE)
    values (?, ?, ?, ?, ?, ?)

  • session.save(stockDailyRecords); ** コードは不要です。 ‘Stock’を保存するときは、保存操作を ‘stockDailyRecords’という名前で “カスケード”し、データベースに自動的に保存します。

カスケード削除の例

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

1.削除カスケードなし

すべての ‘stockDailyRecords’をループし、それを一つずつ削除する必要があります。

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 mkyong.stock__daily__record
    where DAILY__RECORD__ID=?

Hibernate:
    delete from mkyong.stock
    where STOCK__ID=?

2.カスケードを削除する

  • cascade = “delete” ** は ‘stockDailyRecords’で宣言され、削除カスケード効果を有効にします。 ‘Stock’を削除すると、そのすべての参照 ‘stockDailyRecords’が自動的に削除されます。

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="delete" table="stock__daily__record" ...>
      <key>
            <column name="STOCK__ID" not-null="true"/>
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord"/>
</set>

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 mkyong.stock__daily__record
    where DAILY__RECORD__ID=?

Hibernate:
    delete from mkyong.stock
    where STOCK__ID=?

カスケードdelete-orphanの例

上記カスケード削除オプションでは、ストックを削除すると、参照されている ‘stockDailyRecords’もデータベースから削除されます。

2つの参照された ‘stockDailyRecords’レコードを削除したい場合はどうですか?これは孤立した削除と呼ばれ、例を参照してください…​

1. delete-orphanカスケードはありません

‘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 mkyong.stock__daily__record
    where DAILY__RECORD__ID=?
Hibernate:
    delete from mkyong.stock__daily__record
    where DAILY__RECORD__ID=?

2. delete-orphanカスケード

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

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="delete-orphan" table="stock__daily__record" >
      <key>
            <column name="STOCK__ID" not-null="true"/>
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord"/>
</set>

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 mkyong.stock__daily__record
    where DAILY__RECORD__ID=?
Hibernate:
    delete from mkyong.stock__daily__record
    where DAILY__RECORD__ID=?

In short, delete-orphan allow parent table to delete few records (delete
orphan) in its child table.

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

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

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

XMLマッピングファイルでは、関係変数に

cascade

キーワードが宣言されています。

<!-- Stock.hbm.xml -->
<set name="stockDailyRecords" cascade="save-update, delete"
        table="stock__daily__record" ...>
      <key>
            <column name="STOCK__ID" not-null="true"/>
      </key>
      <one-to-many class="com.mkyong.common.StockDailyRecord"/>
</set>

2.注釈

アノテーションでは、@カスケードアノテーションの

CascadeType.SAVE__UPDATE

(save、update)と

CascadeType.REMOVE

(delete)を宣言しました。

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

さらなる研究 – リンク://hibernate/cascade-jpa-hibernate-annotation-common-mistake/[カスケード – JPAとハイバーネーション注釈のよくある間違い]

逆数対カスケード

両方ともまったく異なる概念です。リンク://hibernate/different-between-cascade-and-inverse/[差分はこちら]を参照してください。

結論

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