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 SetgetStockDailyRecords() { 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)。 これで、完全に不変のクラスができましたが、カスケード削除オプションが有効になっている場合、不変のクラスの親が削除されると、不変のクラスも削除されます。