克服Hibernate中的延迟加载问题,多对多关系

Mad*_*mer 6 java hibernate

自学Hibernate,我有以下表结构/关系

关系

这由以下类别代表......

用户

@Entity
@Table(name = "users")
public class User implements IUser<Role>, Serializable {

    @Id
    @GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
    @SequenceGenerator(name = "user_key_seq")
    @Column(name = "key", insertable = false, updatable = false)
    private Long key;

    @Column(name = "name")
    private String name;

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name = "userroles",
                    joinColumns = {
                        @JoinColumn(name = "userkey")},
                    inverseJoinColumns = {
                        @JoinColumn(name = "rolekey")})
    private Set<Role> roles = new HashSet<>(5);

    @Override
    public Set<Role> getRoles() {
        return roles;
    }

    // Other setters and getters

}
Run Code Online (Sandbox Code Playgroud)

角色

@Entity
@Table(name = "roles")
public class Role implements IRole, Serializable {

    @Id
    @GeneratedValue(strategy = javax.persistence.GenerationType.IDENTITY)
    @SequenceGenerator(name = "roles_key_seq")
    @Column(name = "key", insertable = false, updatable = false)
    private Long key;

    @Column(name="name")
    private String name;

    @ManyToMany(cascade = {CascadeType.ALL})
    @JoinTable(name="parentroles",
                    joinColumns = {@JoinColumn(name="childkey")},
                    inverseJoinColumns = {@JoinColumn(name="parentkey")})
    private Set<Role> roles = new HashSet<>(5);

    // Other setters and getters

}
Run Code Online (Sandbox Code Playgroud)

我得到的问题是......

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.kaizen.chishiki.core.data.User.roles, could not initialize proxy - no Session
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142)
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180)
    at og.kaizen.chishiki.core.testdatacore.Main.<init>(Main.java:37)
    at og.kaizen.chishiki.core.testdatacore.Main.main(Main.java:25)
Run Code Online (Sandbox Code Playgroud)

现在,我知道我可以设置fetch类型FetchType.EAGER,但我不想这样做,除了性能问题,我正试图了解这些问题;)

我想知道是否有办法写一个Hibernate查询来满足这种关系并手动加载行(它还允许我返回接口Role而不是实现,因为我现在必须做(允许我保持合同)).

从我读过的内容来看,似乎我需要构建一个Entityfor UserRoles.并不是说我反对这个解决方案,但我很好奇是否有办法绕过它.

roles出现在许多其他关系中,所以它无法与父表形成直接关系(也就是说,我不能直接key将父表的表放在role表中,此外,users可以有多个roles)

我想到的另一个解决方案是编写一个存储过程来为我完成.虽然这是我可以解决的可行解决方案,但它确实使应用程序迁移到另一个数据库更加困难,而不是显示阻止,但我正在努力记住这些想法.

JB *_*zet 4

如果您想要加载用户及其角色,但仍保持关联惰性,请使用包含以下内容的 HQL 查询left join fetch

select u from User u left join fetch u.roles where ...
Run Code Online (Sandbox Code Playgroud)

如果您有一个 User 并且想要确保其角色集合在关闭会话之前已初始化,请调用Hibernate.initialize(user.getRoles())