[解決済み】JPA OneToOneリレーションを遅延させる方法は?
質問
私たちが開発しているこのアプリケーションでは、あるビューが特に遅いことに気づきました。そのビューをプロファイリングしたところ、hibernateによって実行されるクエリが1つあり、フェッチするオブジェクトがデータベース内に2つしかないにもかかわらず10秒かかっていることに気づきました。すべて
OneToMany
と
ManyToMany
リレーションは遅延していたので、問題ではありませんでした。実際に実行されたSQLを調べてみると、クエリに80以上の結合があることに気づきました。
さらに検証を進めると、この問題の原因は
OneToOne
と
ManyToOne
エンティティクラス間の関係です。そこで私は、それらを遅延フェッチさせれば問題が解決するのではないかと考えました。しかし
@OneToOne(fetch=FetchType.LAZY)
または
@ManyToOne(fetch=FetchType.LAZY)
はうまくいかないようです。例外が発生するか、実際にプロキシオブジェクトに置き換えられておらず、その結果、遅延しています。
どうすればうまくいくのか、何かアイデアはありませんか?なお、私は
persistence.xml
を使用してリレーションや設定の詳細を定義し、すべてJavaコードで行っています。
どのように解決するのですか?
まず最初に、以下の点について説明します。 KLE の回答です。
-
制約のない(Nullable)1対1アソシエーションは、バイトコードインスツルメンテーションなしでプロキシされない唯一のものです。その理由は、オーナーエンティティは、associationプロパティがプロキシオブジェクトを含むべきかNULLを含むべきかを知らなければならず、通常1対1は共有PKを介してマッピングされるため、ベーステーブルの列を見てそれを決定できないため、とにかく熱心にフェッチしなければならず、プロキシの意味がないためである。以下は より詳細 を説明します。
-
多対一の関連付けは(もちろん一対多の関連付けも)この問題に悩まされることはありません。所有者エンティティはそれ自身のFKを簡単にチェックできるので (そして1対多の場合、空のコレクションプロキシが最初に作成され、必要に応じて投入されます)、関連付けは怠慢になる可能性があります。
-
一対一を一対多で置き換えることは、決して良いアイデアではありません。ユニークな多対一に置き換えることはできますが、他に(より良い)選択肢があるはずです。
ロブ・H の指摘は正しいのですが、モデルによっては実装できない場合があります(例えば、一対一の関連付けである は nullable)です。
さて、当初の質問の件ですが。
A)
@ManyToOne(fetch=FetchType.LAZY)
は正常に動作するはずです。クエリ自体で上書きされてない?を指定することは可能です。
join fetch
HQL でフェッチモードを設定するか、または Criteria API で明示的にフェッチモードを設定すると、クラスアノテーションより優先されます。そうでなく、まだ問題がある場合は、クラス、クエリ、および結果の SQL を投稿して、より要領よく会話してください。
B)
@OneToOne
は、もっと厄介です。もし確実にnullableでないなら、Rob H.の提案に従って、そのように指定してください。
@OneToOne(optional = false, fetch = FetchType.LAZY)
その他、データベースを変更(ownerテーブルに外部キーカラムを追加)できる場合はそうして、"joined"としてマッピングしてください。
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="other_entity_fk")
public OtherEntity getOther()
とOtherEntityにあります。
@OneToOne(mappedBy = "other")
public OwnerEntity getOwner()
もしそれができないなら(そしてイーガーフェッチに耐えられないなら)、バイトコードインスツルメンテーションが唯一の選択肢となります。私は、以下の意見に賛成です。 CPerkins しかし、もしあなたが 80!!! が、OneToOneの熱心な関連付けのために結合している場合、これより大きな問題があります :-)。
関連
-
[解決済み] android.os.NetworkOnMainThreadException' を修正するにはどうすればよいですか?
-
[解決済み] JVMフラグCMSClassUnloadingEnabledは、実際に何をするのですか?
-
[解決済み] JavaでFileFilterを作るには?
-
[解決済み] java.lang.ClassCastException: java.util.Arrays$ArrayList は java.util.ArrayList にキャストできません。
-
[解決済み] 文字列の長さに応じて文字列をトリミングする
-
[解決済み] JavaFX 同じパッケージ内なのに「場所が必要です。
-
[解決済み] 文字列の巻き方
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] Mavenを使用して、依存関係を持つ実行可能なJARを作成するにはどうすればよいですか?
-
[解決済み】JSP 2を使用して、JSPファイル内のJavaコードを回避するにはどうすればよいですか?
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] tempとは何ですか、またjavaにおけるtempの用途は何ですか?
-
[解決済み] 未処理の例外タイプIOException」が表示されるのですが?
-
[解決済み] java.lang.ClassCastException: java.util.Arrays$ArrayList は java.util.ArrayList にキャストできません。
-
[解決済み] android.support.v4.app.FragmentActivity' で 'TAG' がプライベートアクセスされている。
-
[解決済み] javac ソースファイルが見つかりません
-
[解決済み] Javaでのスキャナが動作しない
-
[解決済み] javax.mail.MessagingException: SMTPホストに接続できませんでしたか?
-
[解決済み] ORA-01654: インデックスを拡張できません。
-
[解決済み] Javaコンパイラーエラー:ステートメントではありません
-
[解決済み] Javaでdoubleをfloatに変換する