0

いくつかのテスト目的で、JUnit テストで LazyInitializationException をスローしようとしています。

私の場合は、3つのエンティティがあることです

@Entity(name = "Role")
public class Role {
    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(mappedBy = "roles", fetch=FetchType.LAZY)
    private Set<AppUser> appUsers;
    ...

}

@Entity(name = "Group")
public class Group {
    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(mappedBy = "groups", fetch=FetchType.LAZY)
    private Set<AppUser> appUsers;
    ...
}

@Entity(name = "AppUser")
public class AppUser {
    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(fetch= FetchType.LAZY)
    @JoinTable(name = "APPUSER_ROLE", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "ID"))
    private Set<Role> roles;
    ...

    @LazyCollection(LazyCollectionOption.TRUE)
    @ManyToMany(fetch= FetchType.LAZY)
    @JoinTable(name = "APPUSER_GROUP", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID"))
    private Set<Group> groups;
    ...

} 

これら 3 つすべてがリレーションを使用して DB に正しく永続化されるテスト データを生成します。次に、トランザクションをコミットします。

しかし、同じテストメソッドでRole(IDに基づいて)読み取ろうとしますが、他のすべての関連エンティティも読み取られます(熱心にロードされているようです)。なぜそうなのですか?どうすれば に来ることができLazyInitializationExceptionますか?

編集: OK、一般的な説明には興味がありません。むしろ、私の場合は開始できないため、コードサンプルが必要です。一般的な説明では問題が解決しません。

4

2 に答える 2

3

LazyInitializationException に到達するにはどうすればよいですか?

あなたが持っているとき:

  1. 遅延読み込みされるエンティティ メンバー (OneToMany や ManyToMany など)
  2. アクティブなトランザクションはありません (エンティティは切り離されています)
  3. メンバーはまだロードされていません
  4. エンティティ メンバーにアクセスしようとすると、遅延読み込みがトリガーされますが、エンティティがデタッチされているためアクセスできません
于 2012-11-12T10:35:02.223 に答える
0

LazyInitializationException問題は、テストメソッド内でトランザクションをコミットした場合でも、セットアップでトリガーするためにEntityManagerも閉じてから再度開く必要があるという事実でした。

最後に、次のエンティティコードになりました。

@Entity(name = "Role")
public class Role {
    @ManyToMany(mappedBy = "roles")
    private Set<AppUser> appUsers;
    ...

}

@Entity(name = "Group")
public class Group {
    @ManyToMany(cascade = {CascadeType.PERSIST})
    @JoinTable(name = "GROUP_APPUSER", joinColumns = @JoinColumn(name = "GROUP_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"))
    private Set<AppUser> appUsers;
    ...
}

@Entity(name = "AppUser")
public class AppUser {
    @ManyToMany(cascade = {CascadeType.PERSIST})
    @JoinTable(name = "APPUSER_ROLE", joinColumns = @JoinColumn(name = "USER_ID", referencedColumnName = "ID"), inverseJoinColumns = @JoinColumn(name = "ROLE_ID", referencedColumnName = "ID"))
    private Set<Role> roles;
    ...

    @ManyToMany(mappedBy = "appUsers")
    private Set<Group> groups;
    ...

} 

ではなく:

Group <- AppUser -> Role

私が持っていた:

Group -> AppUser -> Role

すでに1.stの遅延ロード(Group -> AppUser)で遅延問題が発生したため、タフでも必要ありませんでした。

そして、テストコード自体、最も重要な部分は次のとおりです。

em.getTransaction().begin();
em.persist(group);
em.getTransaction().commit();
em.close();

// reinit em
...

// load group from DB and afterwards close em
em.close();
...
// following throws LazyInitializationException :)
group.getAppUsers().iterator().next();
于 2012-11-12T12:51:20.317 に答える