首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >克服Hibernate、多对多关系中的延迟加载问题

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

Stack Overflow用户
提问于 2014-07-09 21:53:29
回答 3查看 6.7K关注 0票数 6

教自己Hibernate,我有下面的表结构/关系

它由以下类表示..。

用户

代码语言:javascript
复制
@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

}

角色

代码语言:javascript
复制
@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

}

我遇到的问题是.

代码语言:javascript
复制
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)

现在,我知道我可以将fetch类型设置为FetchType.EAGER,但我不想这样做,除了性能方面的考虑,我正在努力学习解决这些问题的方法;)

我想知道是否有一种方法可以编写Hibernate查询来满足这种关系并手动加载行(它还允许我返回Role的接口,而不是我现在不得不做的实现(允许我维护该契约)。

据我所读,我似乎需要为Entity构建一个UserRoles。我并不反对这个解决方案,但我很好奇是否有办法解决这个问题。

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

我想到的另一个解决方案是为我编写一个存储过程。虽然这是一个可行的解决方案,但我并不是这样做的,但它确实使将应用程序迁移到另一个数据库变得更加困难,而不是阻止显示,但我正在努力将这些想法牢记在心。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-09 21:58:15

如果希望加载用户的角色,但仍然延迟关联,请使用包含left join fetch的HQL查询。

代码语言:javascript
复制
select u from User u left join fetch u.roles where ...

如果您有一个用户,并且希望在关闭会话之前初始化它的角色集合,请调用Hibernate.initialize(user.getRoles())

票数 4
EN

Stack Overflow用户

发布于 2015-03-17 03:09:10

如果您正在使用Hibernate 4.1.6+,那么可以通过在hibernate.properties中使用hibernate.enable_lazy_load_no_trans属性来处理这些延迟关联问题。

有关更多信息,请参阅:https://stackoverflow.com/a/11913404/286588

票数 1
EN

Stack Overflow用户

发布于 2017-07-07 05:47:47

我通过注释控制器中的方法来解决这个问题,因为transactional.As延迟加载基本上返回一个未来对象的列表,该方法需要是事务性的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24664388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档