@ManyToOne和@BatchSize
我在一些旧代码中发现了奇怪的事情(至少对我而言)。
注释@ManyToOne
的字段也使用@ManyToOne
注释。
我一直认为@BatchSize
注释只会影响在类级别或集合( @OneToMany
)上注释,并影响迭代时的预取 。
但也许我错了,用@BatchSize
注释@BatchSize
会影响某些东西。 我在文档中找不到答案。
使用@BatchSize
注释@ManyToOne
是否有意义?
只有当相应的字段标记为lazy
( lazy=true
)时,与@ManyToOne
关联的@BatchSize
意义。
实际上,如果字段不是lazy
,那么根据定义已加载,因为加载了封闭实体,因此数据库调用的问题不适用。
想象一下拥有一组ShoesPair
元素( ShoesPair
.class)的Person
类,并且在这一个元素中存在一个标记为lazy的owner
字段(因为在检索特定的一双鞋时,它是可选的并且不会真正带来重要信息)。
一个人想要通过25双鞋(25个ShoesPair
对象)进行迭代,以便找回他们的主人。
如果owner
字段(对应于一个人)仅使用@ManyToOne
注释, @ManyToOne
有25个选择数据库。
但是,如果使用@BatchSize(size=5)
注释, @BatchSize(size=5)
会有5个调用,因此性能会提高。
从Hibernate文档中可以看出,批量大小不仅适用于集合:
您还可以启用批量提取集合。
Hibenate尤其提到@OneToMany
案例,因为这些案例适用于90%的标记为lazy
案例的字段。
我认为这个问题涉及在同一领域组合@ManyToOne
和@BatchSize
,例如:
@ManyToOne @BatchSize(size = 5) private User owner;
Hibernate不支持此用例,至少在使用注释时是这样。 文档中提到的批量提取的唯一用途是:
- 在收集字段上,即
@OneToMany
或@ManyToMany
(但不是@ManyToOne
) - 在要获取的实体类上
例如:
@Entity @BatchSize(size = 5) public class User { ... }
后一种情况允许对User类型的所有关系进行批处理,包括多对一关系。 但是,对于实体类的注释,无法逐个字段地控制行为。
通过Hibernate源代码搜索@BatchSize
所有用途,确认缺少对您的使用的支持。 从我在AnnotationBinder.java中看到的情况来看, @BatchSize
注释仅在实体类和具有某种@XxxToMany
注释的字段上进行检查。
用Hibernate解决N + 1查询问题
1使用带有fetchMode的Criteria查询
标准条件= session.createCriteria(Customer.class); criteria.setFetchMode(“contact”,FetchMode.EAGER);
2 HOL获取连接
3 @BatchSize
@BatchSize注释可用于定义在单个数据库查询中填充的相同关联数。 如果会话有100个客户附加,并且’contact’集合的映射使用大小为n的@BatchSize注释。 这意味着每当Hibernate需要填充延迟联系人集合时,它会检查会话,如果有更多客户需要填充其联系人集合,则最多可以获取n个集合。
@OneToMany(mappedBy="customer",cascade=CascadeType.ALL, fetch=FetchType.LAZY) @BatchSize(size=25) private Set contacts = new HashSet ();