Hibernateの変更可能な例(クラスとコレクション)
休止状態では、クラスとその関連コレクションで ‘
mutable
‘がデフォルトで ‘true’に設定されています。クラスまたはコレクションで追加、更新、削除が許可されています。一方、変数がfalseに変更された場合、クラスとその関連するコレクションでは異なる意味を持ちます。詳細を理解するためにいくつかの例を挙げましょう。
Hibernateの1対多の例
変更可能なデモのためにこのリンクを使います://hibernate/hibernate-one-to-many-relationship-example/[one-to-many例]このマッピングファイルでは、Stockは多くのStockDailyRecordに属します。
<!-- Stock.hbm.xml --> ... <hibernate-mapping> <class name = "com.mkyong.common.Stock" table = "stock"> <set name = "stockDayRecords" mutable = "false" cascade = "all" inverse = "true" lazy = "true" table = "stock__daily__record"> <key> <列名= "STOCK__ID" not-null = "true"/> </key> <one-to-many class = "com.mkyong.common.StockDailyRecord"/> </set> </class> ... </hibernate-mapping>
どのように変数を宣言するのですか?
‘mutable’は、XMLマッピングファイルとアノテーションの両方でサポートされています。
1. XMLマッピングファイル
マッピングファイルでは、 ‘
mutable
‘キーワードは可変関数を実装するために使用されます。
<!-- Stock.hbm.xml --> ... <hibernate-mapping> <class name = "com.mkyong.common.Stock" table = "stock" mutable = "false"> <set name = "stockDayRecords" mutable = "false" cascade = "all" inverse = "true" lazy = "true" table = "stockvd__record"> <key> <列名= "STOCK__ID" not-null = "true"/> </key> <one-to-many class = "com.mkyong.common.StockDailyRecord"/> </set> </class> ... </hibernate-mapping>
2.注釈
アノテーションでは、キーワードは@Immutable(mutable = ‘false’)に変更されます。
... @エンティティ @不変 @Table(name = "stock"、catalog = "mkyong") パブリッククラスStockはjava.io.Serializable { ... @OneToMany(fetch = FetchType.LAZY、mappedBy = "stock") @不変 public Set <StockDailyRecord> getStockDailyRecords(){ これを返す.stockDailyRecords; } ...
Mutable in class
If mutable = “false” or @Immutable is declared in class element, it
means the
updates to this class will be ignored, but no exception is
thrown, only the add and delete operation are allow
.
1. Test insert
株式ストック=新しいストック(); stock.setStockCode( "7277"); stock.setStockName( "DIALOG"); session.save(stock);
mutable = “true”(デフォルト)または@Immutableがclassで宣言されていない場合
出力
休止状態: mkyong.stockに挿入する(STOCK__CODE、STOCK__NAME) 値(?、?)
mutable = “false”または@Immutableがクラスで宣言されている場合
出力
休止状態: mkyong.stockに挿入する(STOCK__CODE、STOCK__NAME) 値(?、?)
2.テストアップデート
株式ストック=(株)session.createQuery( StockCode = '7277' ")。list()。get(0); stock.setStockName( "DIALOG123"); session.saveOrUpdate(stock);
mutable = “true”または@Immutableがclassで宣言されていない場合
出力
休止状態:select ... from mkyong.stock stock0__ where어디에Stock0__.STOCK__CODE = '7277' 休止状態:mkyong.stockを更新します。STOCK__CODE =?、STOCK__NAME =?ここで、STOCK__ID =?
if mutable = “false” or @Immutable is declared in class.
Output
休止状態: 選択してください... mkyong.stock stock0から where0__.STOCK__CODE = '7277'
-
クラス内での変更がアプリケーションの更新を許可していない、 ‘更新’
操作は無視され、例外はスローされません**
3.テストの削除
株式ストック=(株)session.createQuery( StockCode = '7277' ")。list()。get(0); session.delete(stock);
mutable = “true”(デフォルト)または@Immutableがclassで宣言されていない場合
出力
Hibernate:mkyong.stockからどこのSTOCK__ID =?を削除しますか?
if mutable = “false” or @Immutable is declared in class.
Output
Hibernate:mkyong.stockからどこのSTOCK__ID =?を削除しますか?
-
Mutable in class has no effect in the ‘delete’ operation.**
Mutable in collection
If mutable = “false” or @Immutable is declared in collection, it means
the
add and delete-orphan are not allow in this collection, with
exception throw, only update and ‘cascade delete all’ are allow
.
1. Test insert
Assume the cascade insert is enabled.
株式ストック=(株)session.createQuery( StockCode = '7277' ")。list()。get(0); StockDailyRecord sdr = new StockDailyRecord(); sdr.setDate(新しいDate()); sdr.setStock(株); stock.getStockDailyRecords()。add(sdr); session.save(stock);
mutable = “true”(デフォルト)または@Immutableが宣言されていない場合
コレクション。
出力
休止状態: mkyong.stock__daily__recordに挿入 (STOCK__ID、PRICE__OPEN、PRICE__CLOSE、PRICE__CHANGE、VOLUME、DATE) 値(?、?、?、?、?、?)
mutable = “false”または@Immutableがコレクションで宣言されている場合
出力
スレッド "main"の例外org.hibernate.HibernateException: 不変なコレクションインスタンスを変更しました:[com.mkyong.common.Stock.stockDailyRecords#111]
-
Mutable in collection is not allow the ‘add’ operation, an exception
will throw.**
2. Test update
Assume the cascade update is enabled.
株式ストック=(株)session.createQuery( StockCode = '7277' ")。list()。get(0); StockDailyRecord sdr = stock.Stock.getStockDailyRecords()。iterator()。next(); sdr.setPriceChange(新しいフロート(1.30)); session.saveOrUpdate(stock);
mutable = “true”(デフォルト)または@Immutableが宣言されていない場合
コレクション。
出力
休止状態:更新mkyong.stock__daily__recordはPRICE__CHANGE = ?,セット... どこにDAILY__RECORD__ID =?
if mutable = “false” or @Immutable is declared in collection.
Output
休止状態:更新mkyong.stock__daily__recordはPRICE__CHANGE = ?,セット... どこにDAILY__RECORD__ID =?
-
Mutable in collection has no effect in the ‘update’ operation.**
3. Test delete-orphan
Assume the
cascade
delete-orphan
is enabled.
株式ストック=(株)session.createQuery( StockCode = '7277' ")。list()。get(0); StockDailyRecord sdr = stock.Stock.getStockDailyRecords()。iterator()。next(); stock.getStockDailyRecords()。remove(sdr); session.saveOrUpdate(stock);
mutable = “true”(デフォルト)または@Immutableが宣言されていない場合
コレクション。
出力
休止状態:mkyong.stock__daily__recordから削除します。どこでDAILY__RECORD__ID =?
if mutable = “false” or @Immutable is declared in collection.
Output
スレッド "main"の例外org.hibernate.HibernateException: 不変なコレクションインスタンスを変更しました:[com.mkyong.common.Stock.stockDailyRecords#111]
-
Mutable in collection is not allow the ‘delete-orphan’ operation, an
exception will throw.**
4. Test delete
Assume the cascade delete is enabled.
株式ストック=(株)session.createQuery( StockCode = '7277' ")。list()。get(0); session.saveOrUpdate(stock);
mutable = “true”(デフォルト)または@Immutableが宣言されていない場合
コレクション。
出力
休止状態:mkyong.stock__daily__recordから削除します。どこでDAILY__RECORD__ID =? Hibernate:mkyong.stockからどこのSTOCK__ID =?を削除しますか?
if mutable = “false” or @Immutable is declared in collection.
Output
休止状態:mkyong.stock__daily__recordから削除します。どこでDAILY__RECORD__ID =? Hibernate:mkyong.stockからどこのSTOCK__ID =?を削除しますか?
-
Mutable in collection has no effect in the ‘delete’ operation, if
parent is deleted, all its child will be delete as well, even it’s
mutable.**
Why mutable ?
Mutable can avoid many unintentional database operation, like add,
update or delete some records which shouldn’t be. In addition, according
to Hibernate documentation, the mutable do has some minor performance
optimizations, it’s always recommend to analysis your mapping
relationship and implement the mutable as needed.
Summary
1. mutable = “false” or @Immutable is declared in class
it means the updates to this class will be ignored, but no exception is
thrown, only the add and delete operation are allow.
In Class with mutable=”false” – insert=allow, delete=allow , update=not
allow
2. mutable = “false” or @Immutable is declared in collection
it means the add and delete-orphan are not allow in this collection,
with exception throw, only update allow. However, if cascade delete is
enable, when the parent is deleted, all it’s child will be delete as
well, even it is mutable.
In Collection with mutable=”false” – insert=not allow,
delete-orphan=not allow, delete=allow , update=allow
Completely immutable ?
Can a class completely immutable to any actions? Yes, put a
mutable=”false” to all it’s relationship (insert=not allow,
delete-orphan=not allow), and a mutable=”false” to the class you want to
immutable (update=not allow). Now, you have a completely immutable
class, however, if the cascade delete option is enabled, when the parent
of your immutable class is deleted, your immutable class will still be
deleted as well.