Java @ManyTone和@BatchSize
我在一些旧代码中发现了一些奇怪的东西(至少对我来说是这样) 注释为Java @ManyTone和@BatchSize,java,hibernate,hibernate-mapping,hibernate-annotations,Java,Hibernate,Hibernate Mapping,Hibernate Annotations,我在一些旧代码中发现了一些奇怪的东西(至少对我来说是这样) 注释为@ManyToOne的字段也用@BatchSize注释 我一直认为,@BatchSize注释仅在类级别或集合(@OneToMany)上注释时有效,并在迭代时影响预取 但也许我错了,用@BatchSize注释@ManyToOne会影响某些东西。我在文档中找不到答案 用@BatchSize注释@ManyToOne有意义吗?@ManyToOne与@BatchSize相关联的@ManyToOne只有在相应字段标记为惰性时才有意义(lazy
@ManyToOne
的字段也用@BatchSize
注释
我一直认为,@BatchSize
注释仅在类级别或集合(@OneToMany
)上注释时有效,并在迭代时影响预取
但也许我错了,用@BatchSize
注释@ManyToOne
会影响某些东西。我在文档中找不到答案
用
@BatchSize
注释@ManyToOne
有意义吗?@ManyToOne
与@BatchSize
相关联的@ManyToOne
只有在相应字段标记为惰性时才有意义(lazy=true
)
事实上,如果字段不是惰性的
,根据定义,它已经加载了,因为加载了封闭实体,所以数据库调用的问题不适用
假设有一个Person
类拥有一组ShoesPair
元素(ShoesPair
.class),其中有一个owner
字段标记为lazy(因为这是可选的,并且在检索特定鞋款时不会真正带来重要信息)
人们希望遍历25双鞋(25ShoesPair
对象),以检索它们的所有者
如果所有者
字段(对应于一个人)仅用@ManyToOne
注释,则会有25选择数据库
但是,如果使用@BatchSize(size=5)
进行注释,则只会调用5次,从而提高性能
从中可以看出,批量大小不仅适用于集合:
您还可以启用集合的批量提取
@OneToMany(mappedBy="customer",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@BatchSize(size=25)
private Set<Contact> contacts = new HashSet<Contact>();
Hibenate特别提到了@OneToMany
案例,因为这些案例应用的字段在90%的案例中标记为惰性
,我认为问题是指在同一字段上组合@ManyToOne
和@BatchSize
,例如:
@ManyToOne
@BatchSize(size = 5)
private User owner;
Hibernate不支持此用例,至少在使用注释时是这样。报告中提到的批量获取的唯一用途是:
- 在集合字段上,即
@OneToMany
或@ManyToMany
(但不是@manytomone
)
- 在要获取的实体类上
例如:
后一种情况支持对用户类型的所有关系进行批处理,包括多对一关系。但是,通过实体类上的注释,无法逐个字段控制行为
在Hibernate源代码中搜索@BatchSize
的所有用法,可以确认您的用法缺乏支持。从中可以看出,@BatchSize
注释仅在实体类和具有某种@XxxToMany
注释的字段上进行检查。解决了Hibernate的N+1查询问题
1在fetchMode下使用条件查询
条件=session.createCriteria(Customer.class);
criteria.setFetchMode(“contact”,FetchMode.EAGER)
2.获取连接
3@BatchSize
@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>();
@OneToMany(mappedBy=“customer”,cascade=CascadeType.ALL,fetch=FetchType.LAZY)
@批量大小(大小=25)
private Set contacts=new HashSet();
如果它真的像你写的那样工作,我也可以。但我在文档中找不到它。在这里,我只看到这样的内容:“19.1.5.使用批处理获取使用批处理获取,如果访问一个代理,Hibernate可以加载多个未初始化的代理。批处理获取是对惰性选择获取策略的优化。有两种方法可以配置批处理获取:在类级别和集合级别。”我指的是片段:在类级别和集合级别。@ukasz Rzeszotarski我认为文档认为这是非常明显的,这就是为什么没有提到它的原因。事实上,这个概念只适用于惰性对象。我更新了我的答案。也许很明显,也许不是。文档应该涵盖所有的可能性,或者只是以更一般的方式编写——就像您写的“这个概念适用于惰性对象”。但是谢谢你的回答,我会接受的,但是也许有人想添加一些东西。但是在文档中,它解释了一个类似的例子,其中有一个owner
字段。这一个可以标记为nothing作为@ManyToOne
(无事项)。据我所知,你的需求包含在这个例子中。我发现你的答案非常有趣。这似乎与OP接受的答案相矛盾。我不是在检查你的研究,但你说服了我,所以我对你的答案投了赞成票。如果专家能解决这个问题,那就太酷了。