4

私は2日前に怠惰な関連付けの問題に遭遇しましたが、そのような動作の説明はまだ見つかりませんでした。これが私の単純化されたクラス階層です:

@Entity
@Table(name="A")
public class A
{
    @Id
    @GeneratedValue
    @Column(name="ID")
    private int id;
    @OneToMany(mappedBy="a", fetch=FetchType.LAZY, cascade=CascadeType.ALL) 
    private Set<B> listB = new HashSet<B>();
}

@Entity
@Table(name="B")
public class B
{
    @Id
    @GeneratedValue
    @Column(name="ID")
    private int id;
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="A_ID")
    private A a;
    @ManyToOne(fetch=FetchType.LAZY)      // ERROR!
    // @ManyToOne(fetch=FetchType.EAGER)  // OK
    @JoinColumn(name="C_ID")
    private C c;
}

@Entity
@Table(name="C")
public class C {
    @Id
    @GeneratedValue
    @Column(name="ID")
    private int id; 
}

dbから単純な構造を読み取ろうとすると:A->B->C次の結果が得られます。

System.out.println(a.getId());                  // 1
for (B b : a.getListB()) {                      
    System.out.println(b.getId());              // 1
    C c = b.getC();
    System.out.println(c.getId());              // 0 !!!
}

ご覧のとおり、Cのインスタンスは適切に初期化されていません。クラスBのフィールドcのフェッチタイプをLAZYからEAGERに変更すると、すべてが機能します。

CGLIBの魔法があるのではないかと思いますが、仕様にもグーグルにも手がかりが見つかりません。誰かがこれを説明できますか?

助けてくれてありがとう!!!

4

2 に答える 2

1

遅延読み込みを理解したい場合は、この回答を参照してください; それはそれをかなりうまく定義します。

于 2012-08-30T11:01:06.880 に答える
0

修理済み。私の質問は正しくありませんでした。ごめん。私のエンティティクラスのゲッターとセッターには最終的な修飾子がありました。多対多のような単一の値の関連付けを解除します。休止状態のログでいくつかの警告を見逃したとします...この場合、休止状態で例外をスローする方がよいと思います。

于 2012-09-06T13:07:08.257 に答える