inverse = "true"例と解説

逆=「true」の例と説明

Always put inverse=”true” in your collection variable ?
多くのHibernateの記事が、(少なくとも私には)理解するのが非常に難しい多くのHibernateの「公式」専門用語で「逆」を説明しようとしています。 いくつかの記事では、「逆」とは何かを忘れて、常にinverse=”true”をコレクション変数に入れることを提案しています。

このステートメントは常に真です。「コレクション変数にインバース= trueを置く」が、目隠しをせず、Hibernateのパフォーマンスを最適化するために背後にある理由を理解することを試みてください。

「逆」とは何ですか?

これはHibernateで最も紛らわしいキーワードです。少なくとも、理解するにはかなり長い時間がかかりました。 「inverse」キ​​ーワードは常にone-to-manymany-to-manyの関係で宣言されます(多対1には逆キーワードがありません)。これは、どちらの側が処理する責任があるかを意味します。関係。

「逆」、「関係所有者」に変更する必要がありますか?

Hibernateでは、「関係所有者」のみが関係を維持する必要があり、「逆」キーワードが作成されて、関係を維持する所有者がどちら側であるかを定義します。 ただし、「inverse」キーワード自体は十分に冗長ではないため、キーワードを「relationship_owner」に変更することをお勧めします。

つまり、inverse =” true”はこれが関係所有者であることを意味し、inverse =” false”(デフォルト)はそうではないことを意味します。

1. 1対多の関係

これはone-to-many関係テーブルの設計であり、STOCKテーブルにはSTOCK_DAILY_RECORDテーブルで多くのオカレンスがあります。

one to many relationship

2. Hibernateの実装

XMLマッピングファイルのHibernate実装を参照してください。

ファイル:Stock.java

public class Stock implements java.io.Serializable {
   ...
   private Set stockDailyRecords =
                        new HashSet(0);
   ...

ファイル:StockDailyRecord.java

public class StockDailyRecord implements java.io.Serializable {
   ...
   private Stock stock;
   ...

ファイル:Stock.hbm.xml


    
    ...
    
        
            
        
        
    
    ...

ファイル:StockDailyRecord.hbm.xml


  
  ...
  
       
  
  ...

3. 逆= true / false

逆キーワードは1対多の関係で適用されます。 「ストック」オブジェクトで保存または更新操作を実行する場合、「stockDailyRecords」関係を更新する必要がありますか?

ファイル:Stock.hbm.xml

    
    ...
    
        
            
        
        
    
    ...

1. reverse =” true”

セット変数でinverse =” true”の場合、“ stock_daily_record”が関係の所有者であることを意味するため、Stockは関係を更新しません。


    ...
    

2. reverse =” false”

設定変数でinverse =” false”(デフォルト)の場合、「stock」が関係所有者であり、Stockは関係を更新することを意味します。


    ...
    

以下の例を参照してください。

4. inverse =” false”の例

キーワード「inverse」が定義されていない場合、inverse =「false」が使用されます。


    ...
    

これは、「株式」が関係の所有者であり、関係を維持することを意味します。

例を挿入…

「ストック」オブジェクトが保存されると、Hibernateは3つのSQLステートメント、2つの挿入、1つの更新を生成します。

    session.beginTransaction();

    Stock stock = new Stock();
    stock.setStockCode("7052");
    stock.setStockName("PADINI");

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

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

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

    session.getTransaction().commit();

出力…

Hibernate:
    insert
    into
        exampledb.stock
        (STOCK_CODE, STOCK_NAME)
    values
        (?, ?)
Hibernate:
    insert
    into
        exampledb.stock_daily_record
        (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)
Hibernate:
    update
        exampledb.stock_daily_record
    set
        STOCK_ID=?
    where
        RECORD_ID=?

Stockはリレーションシップの所有者であるため、StockはSet変数(stockDailyRecords)を介して「stock_daily_record.STOCK_ID」を更新します。

Note
3番目のステートメントは実際には必要ありません。

更新例…

「ストック」オブジェクトが更新されると、Hibernateは挿入と更新の2つのSQLステートメントを生成します。

    session.beginTransaction();

    Stock stock = (Stock)session.get(Stock.class, 57);

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

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

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

    session.getTransaction().commit();

出力…

Hibernate:
    insert
    into
        exampledb.stock_daily_record
        (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)
Hibernate:
    update
        exampledb.stock_daily_record
    set
        STOCK_ID=?
    where
        RECORD_ID=?

Note
繰り返しますが、3番目のステートメントは必要ありません。

5. inverse =” true”の例

キーワード「inverse = true」が定義されている場合:


    ...
    

これは、「stockDailyRecords」が関係の所有者であり、「stock」が関係を維持しないことを意味します。

例を挿入…

「ストック」オブジェクトが保存されると、Hibernateは2つのSQL挿入ステートメントを生成します。

    session.beginTransaction();

    Stock stock = new Stock();
    stock.setStockCode("7052");
    stock.setStockName("PADINI");

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

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

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

    session.getTransaction().commit();

出力…

Hibernate:
    insert
    into
        exampledb.stock
        (STOCK_CODE, STOCK_NAME)
    values
        (?, ?)
Hibernate:
    insert
    into
        exampledb.stock_daily_record
        (STOCK_ID, PRICE_OPEN, PRICE_CLOSE, PRICE_CHANGE, VOLUME, DATE)
    values
        (?, ?, ?, ?, ?, ?)

更新例…

「Stock」オブジェクトが更新されると、Hibernateは1つのSQLステートメントを生成します。

    session.beginTransaction();

    Stock stock = (Stock)session.get(Stock.class, 57);

    StockDailyRecord stockDailyRecords = new StockDailyRecord();
    stockDailyRecords.setPriceOpen(new Float("1.2"));
    stockDailyRecords.setPriceClose(new Float("1.1"));
    stockDailyRecords.setPriceChange(new Float("10.0"));
    stockDailyRecords.setVolume(3000000L);
    stockDailyRecords.setDate(new Date());

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

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

    session.getTransaction().commit();

出力…

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

inverse vs cascade
多くの人は逆とカスケードを比較するのが好きですが、どちらもまったく異なる概念です。differential hereを参照してください。

結論

Hibernateコードを最適化するには「逆」を理解することが不可欠です。これは、上記の「inverse = falseの例の挿入と更新」のような多くの不要な更新ステートメントを回避するのに役立ちます。 最後に、inverse =” true”を思い出してみてください。これは、関係を処理する関係の所有者であることを意味します。