1

私は同様の質問を見ましたが、答えは私にとってはうまくいきませんでした..

問題:クエリで複数の親エンティティを選択すると、その子エンティティの一部に結合がフェッチされると、クエリはその子エンティティごとにステートメントを@OneToOne実行します。期待どおりに実行されていselectなければ。join fetch


Suserエンティティには関係があります。

@OneToOne(optional = false, fetch = FetchType.LAZY)
@Cascade(value = { CascadeType.PERSIST, CascadeType.DELETE })
public SuserStats stats;

@OneToOne(fetch=FetchType.LAZY)
@Cascade(value = {CascadeType.PERSIST})
public Profile profile;

SuserStats所有者との実体関係;

@OneToOne
@JoinColumn
public Suser owner;

Profile所有者との実体関係;

@OneToOne(optional = false, mappedBy = "profile")
public Suser user;

クエリを実行したとき;

select u from Suser u where u.id in 
  (select f.targetUser.id from Friendship f where f.sourceUser = ?)

予想どおり、1 回のクエリでリレーションの ID のみがフェッチされます。大丈夫です。lazy fetchは働いている..

ただし、変更すると; (今回はそれらを取得したい)

select u from Suser u left join fetch u.stats s left join fetch u.profile where u.id in 
  (select f.targetUser.id from Friendship f where f.sourceUser = ?)

実行中の 2n+1 クエリ..プロファイルと統計関係のそれぞれ。ここで説明されている多くの方法を試しましたが、問題は解決しませんでした。親子関係を定義する際に、基本的なものが欠けていると思います..

前もって感謝します..

4

1 に答える 1

2

私は解決策を見つけました。

注: CascadeType変更は、問題と解決策には関係ありません。

注 2:エンティティに同じ戦略を適用しProfileたので、再度記述する必要はありません

SuserStats実在物;

@MapsId
@OneToOne
@JoinColumn(name="id")
public Suser owner;

Suser実在物;

@OneToOne(mappedBy="owner",optional=false,fetch=FetchType.LAZY,cascade=javax.persistence.CascadeType.PERSIST,javax.persistence.CascadeType.REMOVE})
@PrimaryKeyJoinColumn
public SuserStats stats;

これらの変更により、Statsのプライマリ カラムidSuser(外部キーとして) になりました。そのため、デフォルトの遅延関係と結合フェッチ オンデマンドが機能しています。

于 2013-05-30T00:31:30.827 に答える