[解決済み] Hibernateのレイジーロードアプリケーション設計
2023-05-13 16:42:39
質問
私がよく使うのは ハイバーネート と組み合わせて Spring フレームワークとその宣言的なトランザクションの区分け機能 (例えば @Transactional ).
周知のように、ハイバーネートは
非侵襲的
であり
透明で
を可能な限り実現する必要がありますが、これは
はもう少し難しい
を採用した場合
lazy-loaded
のような関係になります。
透明度の異なるいくつかのデザイン案がありますね。
-
リレーションシップを遅延ロードされないようにする(例.
fetchType=FetchType.EAGER)
- これは、レイジーローディングの考え全体を裏切るものです。
-
コレクションを初期化するには
Hibernate.initialize(proxyObj);
- これは、DAOとの結合が比較的高いことを意味します。
-
でインターフェースを定義することができますが
initialize
で定義できますが、他の実装が同等のものを提供することは保証されません。
-
トランザクションの振る舞いを永続的な
Model
オブジェクト自体にトランザクションの挙動を追加します。 ダイナミックプロキシ または@Transactional
)- 私は動的プロキシのアプローチを試したことはありませんが、永続オブジェクト自体で @Transactional を動作させたことはないようです。おそらく、hibernate がプロキシで動作していることが原因だと思います。
- トランザクションが実際に行われているときに制御が失われる
-
遅延/非遅延APIの両方を提供する、例えば
loadData()
とloadDataWithDeps()
- アプリケーションに、いつどのルーチンを使用するかを知らせることで、再び緊密な結合を実現します。
-
メソッドのオーバーフロー。
loadDataWithA()
, ....,loadDataWithX()
-
依存関係のルックアップを強制する。
byId()
操作-
オブジェクト指向でないルーチンを多く必要とする、例.
findZzzById(zid)
とか、それからgetYyyIds(zid)
の代わりにz.getY()
- トランザクション間に大きな処理オーバーヘッドがある場合、コレクション内の各オブジェクトを1つずつフェッチするのが便利なことがあります。
-
オブジェクト指向でないルーチンを多く必要とする、例.
-
の一部を
アプリケーション
のみの代わりに @Transactional を使用します。
DAO
- ネストされたトランザクションの可能な考慮事項
- トランザクション管理に適合したルーチンを必要とする(例えば、十分に小さい)。
- 大きなトランザクションを引き起こすかもしれませんが、プログラムへの影響は小さいです。
-
DAOに動的な
プロファイルを取得する
, 例,
loadData(id, fetchProfile);
- アプリケーションは、以下の場合にどのプロファイルを使用するかを知っている必要があります。
-
AoP型のトランザクション、例えば操作を傍受し、必要な時にトランザクションを実行する。
- バイトコード操作またはプロキシ利用が必要
- トランザクションの実行時に制御不能になる
- いつものように黒魔術 :)
何かオプションを見逃しましたか?
の影響を最小限に抑えようとする場合、どのようなアプローチが望ましいですか?
lazy-loaded
の関係の影響を最小化しようとする場合、どちらのアプローチが好ましいですか?
(あ、それと申し訳ないのですが WoT )
どのように解決するのですか?
<ブロッククオート周知のように、hibernate は可能な限り非侵襲的で透過的であろうとします。
最初の仮定は間違っていると言えるでしょう。なぜなら、アプリケーションは常にエンティティのライフサイクルと読み込まれるオブジェクトグラフのサイズに気を配らなければならないからです。
Hibernateは思考を読み取ることができないので、特定の操作のために特定の依存関係のセットが必要であることが分かっている場合、何らかの方法でHibernateに意図を伝える必要があることに注意してください。
この観点から、これらの意図を明示的に表現するソリューション(すなわち、2、4、7)は合理的に見え、透明性の欠如に悩まされることはありません。
関連
-
Springの設定でxsdファイルのバージョン番号を設定しない方が良い理由
-
Javaクラスが "Error occurred during initialization of boot layer "というエラーで実行される。
-
強制型変換について
-
unsigned char* から const jbyte* {aka const signed char*} への変換が無効です。
-
List list = new ArrayList(); Error: ArrayList は型に解決できません。
-
FindBugの使用概要
-
linux ant Resolve error: main class not found or couldn't be loaded org.apache.tools.ant.launcher.
-
[解決済み] Could not find or load main class "とはどういう意味ですか?
-
[解決済み] Spring Bootアプリケーションにポートを設定する方法
-
[解決済み] Java Persistence APIにおけるFetchType LAZYとEAGERの違い?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
javaの非静的メソッドを静的に参照することができない
-
Solve モジュールのビルドに失敗しました。Error: ENOENT: no such file or directory エラー
-
Jsoup-Crawlingの動作
-
シェルコマンドやスクリプトのJavaコール
-
SpringBoot 起動エラー java.nio.charset.MalformedInputException: 入力長 = 2 解決
-
List list = new ArrayList(); Error: ArrayList は型に解決できません。
-
アノテーション「@Retention」の役割
-
java send https request prompt java.security.cert.について。
-
コンストラクタDate()が未定義である問題
-
ecplise プロンプトが表示されます。"選択したものは起動できません。" "最近の起動はありません。"