java @ManyToOne 和 @BatchSize
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13048436/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@ManyToOne and @BatchSize
提问by ?ukasz Rzeszotarski
I found in some old code strange thing (at least for me).
我在一些旧代码中发现了奇怪的东西(至少对我而言)。
The field which is annotated @ManyToOne
is also annotated with @BatchSize
.
注释的字段@ManyToOne
也用 注释@BatchSize
。
I always thought that @BatchSize
annotation only affects when annotated at class level or on a collection (@OneToMany
) and affects pre-fetchingwhen iterating.
我一直认为@BatchSize
注解只会在类级别或集合 ( @OneToMany
)上注解时影响,并在迭代时影响预取。
But maybe I am wrong and annotating @ManyToOne
with @BatchSize
affects something. I can't find the answer in the documentation.
但是,也许我错了,并标注@ManyToOne
与@BatchSize
影响的东西。我在文档中找不到答案。
Does annotating @ManyToOne
with @BatchSize
have sense?
是否标注@ManyToOne
有@BatchSize
有感觉?
采纳答案by Mik378
@ManyToOne
associated with @BatchSize
could make sense only if the corresponding field is marked as lazy
(lazy=true
).
@ManyToOne
@BatchSize
仅当相应的字段标记为lazy
( lazy=true
) 时,与关联才有意义。
Indeed, if the field is not lazy
, it's by definition already loaded since the enclosing entity is loaded, so the problem of database calls doesn't apply.
实际上,如果该字段不是lazy
,则根据定义,它在加载封闭实体后已经加载,因此数据库调用的问题不适用。
Imagine a Person
class who has a collection of ShoesPair
element (ShoesPair
.class) and within this one is present an owner
field marked as lazy (since optional and not really bringing an important information when retrieving a specific pair of shoes).
想象一个Person
拥有ShoesPair
元素集合( ShoesPair
.class)的类,其中存在一个owner
标记为惰性的字段(因为是可选的,并且在检索特定的鞋子时并没有真正带来重要信息)。
One wants to iterate through 25pair of shoes (25 ShoesPair
objects) in order to retrieve their owner.
一个人想要遍历25双鞋(25 个ShoesPair
对象)以找回它们的主人。
If the owner
field (corresponding to one person) is only annotated with @ManyToOne
, there would be 25select to database.
如果owner
字段(对应一个人)只标注了@ManyToOne
,那么数据库就有25 个选择。
However, if annoted with @BatchSize(size=5)
, there would be merely 5calls and so increasing performance.
但是,如果用 注释,则只@BatchSize(size=5)
会有5 次调用,从而提高性能。
From the Hibernate documentation, it is precised that batch size does not only apply with collections:
从Hibernate 文档中可以看出,批量大小不仅适用于集合:
You can alsoenable batch fetching of collections.
您还可以启用批量提取集合。
Hibenate mentions especially @OneToMany
cases, because these one are applied with fields that are in 90% of cases marked as lazy
.
Hibenate 特别提到了@OneToMany
案例,因为这些案例应用于 90% 的案例中标记为的字段lazy
。
回答by chris
I think the question refers to combining @ManyToOne
and @BatchSize
on the same field, e.g.:
我认为这个问题是指在同一领域合并@ManyToOne
和@BatchSize
,例如:
@ManyToOne
@BatchSize(size = 5)
private User owner;
This use case is not supported by Hibernate, at least when using annotations. The only uses of batch fetching mentioned by the documentationare:
Hibernate 不支持此用例,至少在使用注释时是这样。文档中提到的批量获取的唯一用途是:
- On collection fields, i.e.,
@OneToMany
or@ManyToMany
(but not@ManyToOne
) - On the entity class to be fetched
- 在集合字段上,即,
@OneToMany
或@ManyToMany
(但不是@ManyToOne
) - 在要获取的实体类上
E.g.:
例如:
@Entity
@BatchSize(size = 5)
public class User {
...
}
This latter case enables batching for all relationships of type User, including many-to-one relationships. However, with the annotation on the entity class it is not possible to control the behaviour on a field-by-field basis.
后一种情况支持对 User 类型的所有关系进行批处理,包括多对一关系。但是,通过实体类上的注释,无法逐个字段地控制行为。
A search through the Hibernate source code for all uses of @BatchSize
confirms the lack of support for your usage. From what I see in AnnotationBinder.java, the @BatchSize
annotation is only inspected on the entity class and on fields which have some kind of @XxxToMany
annotation.
搜索所有使用的 Hibernate 源代码@BatchSize
证实缺乏对您的使用的支持。从我在AnnotationBinder.java 中看到的,@BatchSize
仅在实体类和具有某种@XxxToMany
注释的字段上检查注释。
回答by Sagar Misal
Solving N+1 query problem with Hibernate
用Hibernate解决N+1查询问题
1 Using Criteria queries with fetchMode
1 使用带有 fetchMode 的 Criteria 查询
Criteria criteria = session.createCriteria(Customer.class); criteria.setFetchMode("contact", FetchMode.EAGER);
标准标准 = session.createCriteria(Customer.class); 标准.setFetchMode(“联系”,FetchMode.EAGER);
2 HOL fetch join
2 HOL 获取连接
3 @BatchSize
3 @BatchSize
The @BatchSize annotation can be used to define how many identical associations to populate in a single database query. If the session has 100 customers attached to it and the mapping of the 'contact' collection is annotated with @BatchSize of size n. It means that whenever Hibernate needs to populate a lazy contact collection it checks the session and if it has more customers which their contact collections need to be populated it fetches up to n collections.
@BatchSize 注释可用于定义在单个数据库查询中填充多少相同的关联。如果会话附加了 100 个客户,并且“联系人”集合的映射使用大小为 n 的 @BatchSize 进行注释。这意味着每当 Hibernate 需要填充一个惰性联系人集合时,它会检查会话,如果它有更多的客户需要填充他们的联系人集合,它会获取最多 n 个集合。
@OneToMany(mappedBy="customer",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@BatchSize(size=25)
private Set<Contact> contacts = new HashSet<Contact>();