Hibernate 多对多将触发多侧选择,即使这些实体已加载 用户(m:m)书籍 类用户:: @许多 @批量大小(大小=100) 公开书目; loadAllActivateUsers() foreach用户 do(user.books)
假设user1拥有书籍(1-5),user2拥有相同的书籍 调用user.books时,hibernate将触发对load book的完整查询,即使这些书籍已经加载。 Hibernate不会对这些数据什么都不做,因为实体已经在会话中,但是当book是“大实体”并且加载了大量用户时,冗余获取就会成为性能问题 我希望有一种方法来定义hibernate将触发对关联表的查询,并且如果该键已经在会话中,则不会触发对它的查询。这是意料之中的 假设我首先加载用户“John”。约翰拥有《白鲸》和《哈姆雷特》两本书。现在我加载用户“Mary”。Hibernate怎么知道Mary拥有哪本书?也许她拥有《白鲸记》,也许不是。也许她拥有哈姆雷特,也许不是。也许她还有200本书,也许没有。所以Hibernate执行一个查询来加载Mary拥有的所有书籍。如果Mary碰巧拥有一本以前加载过的书,那么内存中只会存在这本书的一个实例 如果需要,可以在单个查询中加载用户及其书籍:Hibernate 多对多将触发多侧选择,即使这些实体已加载 用户(m:m)书籍 类用户:: @许多 @批量大小(大小=100) 公开书目; loadAllActivateUsers() foreach用户 do(user.books),hibernate,Hibernate,假设user1拥有书籍(1-5),user2拥有相同的书籍 调用user.books时,hibernate将触发对load book的完整查询,即使这些书籍已经加载。 Hibernate不会对这些数据什么都不做,因为实体已经在会话中,但是当book是“大实体”并且加载了大量用户时,冗余获取就会成为性能问题 我希望有一种方法来定义hibernate将触发对关联表的查询,并且如果该键已经在会话中,则不会触发对它的查询。这是意料之中的 假设我首先加载用户“John”。约翰拥有《白鲸》和《哈姆雷特》两本
user(m:m)books
class user::
@ManyToMany
@BatchSize(size=100)
public List<Book> books;
loadAllActiveUsers()
foreach user
do(user.books)
hibernate可以通过触发两步查询来了解这一点:首先从关联表加载关联id,然后加载尚未加载的关联实体。在许多多对多用例中,实体与多个所有者关联,因此有可能关联的实体已经加载。当实体具有一对多关系时,fetch join不是一个好主意。任何方式,即使是查询简单实体,也会产生1M行。
select u from User u left join fetch u.books