Hibernateの変更可能な例(クラスとコレクション)

Hibernateの可変の例(クラスとコレクション)

Hibernateでは、クラスとそれに関連するコレクションで「mutable」はデフォルトで「true」になります。つまり、クラスまたはコレクションで追加、更新、削除が許可されます。 一方、mutableがfalseに変更されると、クラスとその関連コレクションで異なる意味を持ちます。 それをもっと理解するためにいくつかの例を取り上げましょう。

Hibernateの1対多の例

このone-to-many exampleを変更可能なデモンストレーションに使用します。 このマッピングファイルでは、Stockは多くのStockDailyRecordに属します。

...

    
        
            
                
            
            
        
    
...

可変を宣言する方法は?

「可変」は、XMLマッピングファイルと注釈の両方でサポートされています。

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

マッピングファイルでは、 ‘mutable‘キーワードを使用して可変関数を実装します。

...

    
        
            
                
            
            
        
    
...

2. アノテーション

アノテーションでは、キーワードは@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 Set getStockDailyRecords() {
        return this.stockDailyRecords;
    }
...

クラス内で可変

mutable =“ false”または@Immutableがクラス要素で宣言されている場合、それはupdates to this class will be ignored, but no exception is thrown, only the add and delete operation are allowを意味します。

1. テスト挿入

Stock stock = new Stock();
stock.setStockCode("7277");
stock.setStockName("DIALOG");
session.save(stock);

mutable =“ true”(デフォルト)の場合、またはクラスで@Immutableが宣言されていない場合。
Output

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

mutable =“ false”または@Immutableがクラスで宣言されている場合
Output

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

クラスで変更可能は、「挿入」操作には影響しません。

2. テスト更新

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
stock.setStockName("DIALOG123");
session.saveOrUpdate(stock);

mutable =“ true”の場合、または@Immutableがクラスで宣言されていない場合。
Output

Hibernate:
    select ...from example.stock stock0_
    where stock0_.STOCK_CODE='7277'

Hibernate:
    update example.stock
    set STOCK_CODE=?,STOCK_NAME=?
    where STOCK_ID=?

mutable =“ false”または@Immutableがクラスで宣言されている場合
Output

Hibernate:
    select ...from example.stock stock0_
    where stock0_.STOCK_CODE='7277'

クラス内で変更可能であるため、アプリケーションはそれを更新できません。「更新」操作は無視され、例外はスローされません。

3. テスト削除

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
session.delete(stock);

mutable =“ true”(デフォルト)の場合、またはクラスで@Immutableが宣言されていない場合。
Output

Hibernate:
    delete from example.stock
    where STOCK_ID=?

mutable =“ false”または@Immutableがクラスで宣言されている場合
Output

Hibernate:
    delete from example.stock
    where STOCK_ID=?

クラスで変更可能は、「削除」操作には影響しません。

コレクション内で変更可能

mutable =“ false”または@Immutableがコレクションで宣言されている場合、それはadd and delete-orphan are not allow in this collection, with exception throw, only update and ‘cascade delete all’ are allowを意味します。

1. テスト挿入

カスケード挿入が有効になっていると仮定します。

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

mutable =“ true”(デフォルト)の場合、またはコレクションで@Immutableが宣言されていない場合。
Output

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

mutable =“ false”または@Immutableがコレクションで宣言されている場合。
Output

Exception in thread "main" org.hibernate.HibernateException:
changed an immutable collection instance:
[com.example.common.Stock.stockDailyRecords#111]

コレクション内の可変は「追加」操作を許可していません。例外がスローされます。

2. テスト更新

カスケード更新が有効になっていると仮定します。

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

mutable =“ true”(デフォルト)の場合、またはコレクションで@Immutableが宣言されていない場合。
Output

Hibernate:
    update example.stock_daily_record
    set PRICE_CHANGE=?, ...
    where DAILY_RECORD_ID=?

mutable =“ false”または@Immutableがコレクションで宣言されている場合。
Output

Hibernate:
    update example.stock_daily_record
    set PRICE_CHANGE=?, ...
    where DAILY_RECORD_ID=?

コレクション内の可変は、「更新」操作には影響しません。

3. 削除オーファンのテスト

cascade delete-orphanが有効になっていると仮定します。

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

mutable =“ true”(デフォルト)の場合、またはコレクションで@Immutableが宣言されていない場合。
Output

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

mutable =“ false”または@Immutableがコレクションで宣言されている場合。
Output

Exception in thread "main" org.hibernate.HibernateException:
changed an immutable collection instance:
[com.example.common.Stock.stockDailyRecords#111]

コレクション内の可変では、「孤立した削除」操作は許可されていません。例外がスローされます。

4. テスト削除

カスケード削除が有効になっていると仮定します。

Stock stock = (Stock)session.createQuery(
      " from Stock where stockCode = '7277'").list().get(0);
session.saveOrUpdate(stock);

mutable =“ true”(デフォルト)の場合、またはコレクションで@Immutableが宣言されていない場合。
Output

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

mutable =“ false”または@Immutableがコレクションで宣言されている場合。
Output

Hibernate:
    delete from example.stock_daily_record
    where DAILY_RECORD_ID=?

Hibernate:
    delete from example.stock
    where STOCK_ID=?

コレクション内の変更可能は「削除」操作には影響しません。親が削除されると、変更可能であっても、そのすべての子も削除されます。

なぜ可変なのか?

Mutableは、あるべきではないレコードの追加、更新、削除など、多くの意図しないデータベース操作を回避できます。 さらに、Hibernateのドキュメントによると、mutableにはいくつかのマイナーなパフォーマンス最適化があります。マッピング関係を分析し、必要に応じてmutableを実装することを常にお勧めします。

概要

1. mutable =“ false”または@Immutableがクラスで宣言されています

つまり、このクラスへの更新は無視されますが、例外はスローされず、追加および削除操作のみが許可されます。

mutable =” false”のクラス– insert = allow、delete = allow、update = not allow

2. mutable =“ false”または@Immutableがコレクションで宣言されています

つまり、addおよびdelete-orphanはこのコレクションでは許可されず、例外がスローされ、更新のみが許可されます。 ただし、カスケード削除が有効になっている場合、親が削除されると、その子もすべて、たとえ変更可能であっても削除されます。

mutable =” false”のコレクション内– insert = not allow、delete-orphan = not allow、delete = allow、update = allow

完全に不変ですか?

クラスはアクションに対して完全に不変ですか? はい、すべての関係にmutable =” false”を入れ(insert = not allow、delete-orphan = not allow)、不変にするクラスにmutable =” false”を入れます(update = not allow)。 これで、完全に不変のクラスができましたが、カスケード削除オプションが有効になっている場合、不変のクラスの親が削除されると、不変のクラスも削除されます。