1

次のエンティティがあります。

//The class Entity is a @MappedSuperclass with id, audit fields, equals and so on.
@Entity
public class Foo extends Entity {
    @OneToMany(mappedBy = "foo", cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Bar> bars = new HashSet<Bar>; // + getter/setter

    // ... other properties
}

@Entity
public class Bar extends Entity {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "foo_id")
    private Foo foo; // +getter/setter

    @OneToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "baz_id", nullable = false)
    private Baz baz; // + getter/setter

    // ... other properties
}

@Entity
public class Baz extends Entity {
    @OneToOne(mappedBy = "baz", fetch = FetchType.LAZY, optional = false)
    private Bar bar; // + getter/setter

    // ... other properties
}

ここで、次のものをロードするBarと、すべて問題ありません (つまり、1 つのクエリのみが DB に送信されます)。

SELECT bar FROM Bar bar LEFT JOIN FETCH bar.baz WHERE bar.id = :barId

ただし、次のいずれかを実行すると、関連付けられたオブジェクトを取得するSELECTためにすべての新しいオブジェクトが作成されます。BazBar

SELECT f FROM Foo f LEFT JOIN FETCH f.bars bar LEFT JOIN FETCH bar.baz WHERE f.id = :fooId
SELECT f FROM Foo f LEFT JOIN FETCH f.bars bar LEFT JOIN FETCH bar.baz baz LEFT JOIN FETCH baz.bar WHERE f.id = :fooId

出力は次のとおりです。

10:52:08,622 INFO  [STDOUT] Hibernate: select ... from Foo ...
10:52:08,698 INFO  [STDOUT] Hibernate: select ... from Bar where baz_id=?
10:52:08,711 INFO  [STDOUT] Hibernate: select ... from Bar where baz_id=?
... and so on

さて、遅延読み込みに問題があるこの回答から理解したので@OneToOne、彼らのアドバイスに従い、 optional = false を追加しました(これは私にはあまり効果がなかったようです)。

このブログ投稿の提案 3 も試しましたが、まったく効果がないようです。

SELECT n+1 の問題を回避するためにオブジェクト グラフを積極的に取得する方法について何か提案はありますか?

JBoss 4.2 サーバー上の Hibernate 3.2.4.sp1 で EJB 3 (JPA 1) を使用しています。

注: これは、私の以前の質問の 1 つに多少似ています。違いは、ここに問題があると思われるBaz参照があることです。Bar

4

1 に答える 1

0

Baz から Bar への後方参照を削除することで、この問題を回避できました。根本的な原因、または余分な選択なしでオブジェクトを熱心にロードする方法が見つかりませんでした。

于 2013-06-06T07:37:36.050 に答える