私が開発しようとしているアプリケーションでは、Hibernateをデータベースからメモリにたくさんの永続オブジェクトを取得するために排他的に使用しています。アプリケーションは、このインメモリスナップショットをデータベースから毎回更新し、それがデータベースとの唯一の通信である必要があります。Hibernateマップセットを変更不可能なセットとしてロードするにはどうしたらいいですか?
メモリ内のオブジェクトは、一連の計算に使用されます。計算でこれらのオブジェクトを変更してはいけません。何らかのクラスを間違ってやったことを除いて、私はバグを狩る日を過ごさなければならなかった。今私はオブジェクトツリー全体を不変にする最良の方法が何であるか疑問に思っています。熱心にすべてのエンティティとコレクションをマークし、すべてのエンティティとコレクション
- :私はしてデータベースにアクセスするクライアントを妨げてきた
public class Building { // persistent entity private String name; // hibernate-mapped property private Set<Person> inhabitants; // hibernate-mapped collection // getters } public class Person { // persistent entity private String name; // hibernate-mapped property // getters }
:
は、クラス階層は次のようになりますと仮定しますHibernateマッピングで
mutable=false
を使用している場合 - Hibernateセッションのインスタンスを提供していないか、またはstate-changin g DAOメソッド。
ここで私が避けたいエラーは、誤ってbuilding.getInhabitants().clear();
に行くことです。そして、それを返す、Collections.unmodifiableSet()
コールにgetInhabitants
最初のラップinhabitants
を行います
ゲッターはをラップ:私は、これらのオプションを考えることができます。
- 長所:最小仕事、少なくとも余分なコード
- 短所:
Building
、MutableBuilding
からPerson
MutablePerson
に名前を変更し、不変クラスBuilding
とPerson
を提供:ハック
ラッパークラスが感じます。私のアプリケーションは明確なスナップショットポイントを持っているので、(私が今行っているように)変更可能なオブジェクトとしてレコードをフェッチし、深く不変なコピーを作成し、そのオブジェクトツリーをクライアントに提示することができます。
- 長所:ストレートjava、休止状態の魔法。私は私の好きなキーワードを使用するようになる:
final
- 短所:より多くのコードを書いて維持する。また、Hibernateは変更可能なインスタンスをメモリに保持しますか?
- 長所:ストレートjava、休止状態の魔法。私は私の好きなキーワードを使用するようになる:
Hibernateマッピング魔法は:1つの魔法のキーワードは
Collections.unmodifiableSet()
または同等で私のエンティティオブジェクトのそれはセットのコレクションをラップするために休止状態を指示することを使用します。(注:私は、XMLマッピングファイルを使用します)- 長所:エレガント、余分なコード
- 短所:1つのHibernateの延長という用途:このようなキーワードは
Hibernateの拡張存在しないかもしれないが私自身のオブジェクトインスタンシエータを書くことを指し、それを返す前に
Collections.unmodifiableSet()
にセットをラップします。- 長所:このような拡張ポイント
存在しないかもしれない今、私は私がいない主な理由は、#2の方に傾いています:
どのような方法が最適ですか?
私がゲッターとセッターを書く理由を思い出させるために+1: – KarlP
これは最善の解決策のようです。私は、変わるクラスがときどき大丈夫だという事実を条件にしなければならないでしょう! :) – oksayt