Hibernate一对多双向关系效率较低

5

我有以下带有双向 OneToMany 映射的 SessionsUsers 类(使用 Hibernate 反向工程工具生成):

public class Users {
    @OneToMany(fetch=FetchType.LAZY, mappedBy="users")
    public Set<Sessions> getSessionses() {
        return this.sessionses;
    }
}

public class Sessions {
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="USER_ID")
    public Users getUsers() {
        return this.users;
    }
}

这是创建新用户会话的代码:

Session s = ...;
Users user = (Users) s.createCriteria(Users.class)
             ./*restrictions...*/.uniqueResult();
Sessions userSession = new Sessions();
userSession.setUsers(user);
s.save(userSession);
user.getSessionses().add(userSession); // here getSessionses() has 2k records

用户有2k个会话,因此最后一行非常缓慢。

如何在不获取整个会话集合的情况下将会话与用户链接?


你如何加载 user 实体? - Balázs Németh
1
你真的需要集合是一个Set吗?当你向其中添加元素时,Hibernate需要加载元素以检查重复。 - Guillaume
@Guillaume Set是Hibernate强制使用的维护唯一性的数据结构。 - sanbhat
当你有唯一的ID时,结果已经是独一无二的了。但是使用列表可以加快处理速度。 - Lukas Eichler
这可能是一个重复的问题:https://dev59.com/xHM_5IYBdhLWcg3wXx1N - Balázs Németh
2个回答

4
请查看Hibernate的extra-lazy loading功能。您可以通过在集合上注释@LazyCollection(LazyCollectionOption.EXTRA)来启用它。有这个例子可以参考,还有这个中使用的Set
public class Users {
    @OneToMany(fetch=FetchType.LAZY, mappedBy="users")
    @LazyCollection(LazyCollectionOption.EXTRA)
    public Set<Sessions> getSessionses() {
        return this.sessionses;
    }
}

太好了,谢谢!它完美地工作了。在这种情况下,Hibernate 只生成单个查询:SELECT 1 FROM SESSIONS WHERE USER_ID=? and SESSION_ID=?。这是唯一的解决方案,可以在不将 Set<Sessions> 更改为 List<Sessions> 的情况下帮助解决问题。 - Oleksandr.Bezhan

1
我不确定Hibernate是否会双向添加此连接,但是可以将Session添加到User集合中,而是将User添加到Session中。这样就不必加载每个会话了。

1
Hibernate doc指出:“在双向链接中,必须在两侧设置链接”,因此需要在两侧设置链接。 - Oleksandr.Bezhan
你能否提供任何官方文件证明链接来反驳我的评论? - Oleksandr.Bezhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接