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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 11:19:06  来源:igfitidea点击:

@ManyToOne and @BatchSize

javahibernatehibernate-mappinghibernate-annotations

提问by ?ukasz Rzeszotarski

I found in some old code strange thing (at least for me).

我在一些旧代码中发现了奇怪的东西(至少对我而言)。

The field which is annotated @ManyToOneis also annotated with @BatchSize.

注释的字段@ManyToOne也用 注释@BatchSize

I always thought that @BatchSizeannotation 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 @ManyToOnewith @BatchSizeaffects something. I can't find the answer in the documentation.

但是,也许我错了,并标注@ManyToOne@BatchSize影响的东西。我在文档中找不到答案。

Does annotating @ManyToOnewith @BatchSizehave sense?

是否标注@ManyToOne@BatchSize有感觉?

采纳答案by Mik378

@ManyToOneassociated with @BatchSizecould 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 Personclass who has a collection of ShoesPairelement (ShoesPair.class) and within this one is present an ownerfield 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 ShoesPairobjects) in order to retrieve their owner.

一个人想要遍历25双鞋(25 个ShoesPair对象)以找回它们的主人。

If the ownerfield (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 @OneToManycases, 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 @ManyToOneand @BatchSizeon 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., @OneToManyor @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 @BatchSizeconfirms the lack of support for your usage. From what I see in AnnotationBinder.java, the @BatchSizeannotation is only inspected on the entity class and on fields which have some kind of @XxxToManyannotation.

搜索所有使用的 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>();