Java Hibernate 中一对一、多对一和一对多的默认获取类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26601032/
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
Default fetch type for one-to-one, many-to-one and one-to-many in Hibernate
提问by Richa
What is the default fetch type in hibernate mappings?
休眠映射中的默认获取类型是什么?
What I got to know after exploring is:
探索之后我了解到的是:
- for one-to-one it is eager.
- for one-to-many it is lazy.
- 对于一对一,它是渴望的。
- 对于一对多,它是惰性的。
But after testing it in Eclipse, it was eager for all.
但是在 Eclipse 中对其进行测试后,它对所有人都非常渴望。
Does it depend on whether I am using JPA or Hibernate?
这取决于我使用的是 JPA 还是 Hibernate?
采纳答案by Ashish Agarwal
It depends on whether you are using JPA or Hibernate.
这取决于您使用的是 JPA 还是 Hibernate。
From the JPA 2.0 spec, the defaults are:
从JPA 2.0 规范中,默认值是:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
And in hibernate, all is Lazy
而在休眠状态下,一切都是懒惰的
UPDATE:
更新:
The latest version of Hibernate aligns with the above JPA defaults.
最新版本的 Hibernate 与上述 JPA 默认值一致。
回答by JamesENL
To answer your question, Hibernate is an implementation of the JPA standard. Hibernate has its own quirks of operation, but as per the Hibernate docs
为了回答您的问题,Hibernate 是 JPA 标准的实现。Hibernate 有自己的操作怪癖,但根据Hibernate 文档
By default, Hibernate uses lazy select fetching for collections and lazy proxy fetching for single-valued associations. These defaults make sense for most associations in the majority of applications.
默认情况下,Hibernate 对集合使用惰性选择获取,对单值关联使用惰性代理获取。这些默认值对大多数应用程序中的大多数关联都有意义。
So Hibernate will always load any object using a lazy fetching strategy, no matter what type of relationship you have declared. It will use a lazy proxy (which should be uninitialized but not null) for a single object in a one-to-one or many-to-one relationship, and a null collection that it will hydrate with values when you attempt to access it.
因此 Hibernate 将始终使用延迟获取策略加载任何对象,无论您声明什么类型的关系。它将为一对一或多对一关系中的单个对象使用一个惰性代理(它应该是未初始化但不是空的),以及一个空集合,当您尝试访问它时它将与值水合.
It should be understood that Hibernate will only attempt to fill these objects with values when you attempt to access the object, unless you specify fetchType.EAGER
.
应该理解,Hibernate 只会在您尝试访问对象时尝试用值填充这些对象,除非您指定 fetchType.EAGER
.
回答by Alexander Rühl
I know the answers were correct at the time of asking the question - but since people (like me this minute) still happen to find them wondering why their WildFly 10 was behaving differently, I'd like to give an update for the current Hibernate 5.x version:
我知道在提出问题时答案是正确的 - 但由于人们(像我这样的人)仍然碰巧发现他们想知道为什么他们的 WildFly 10 表现不同,我想提供当前 Hibernate 5 的更新.x 版本:
In the Hibernate 5.2 User Guideit is stated in chapter 11.2. Applying fetch strategies:
在Hibernate 5.2 用户指南中,它在第11.2章中有说明。应用获取策略:
The Hibernate recommendation is to statically mark all associations lazy and to use dynamic fetching strategies for eagerness. This is unfortunately at odds with the JPA specification which defines that all one-to-one and many-to-one associations should be eagerly fetched by default. Hibernate, as a JPA provider, honors that default.
Hibernate 建议将所有关联静态标记为惰性,并使用动态获取策略来实现渴望。不幸的是,这与 JPA 规范不一致,该规范定义 默认情况下应急切地获取所有一对一和多对一关联。作为 JPA 提供者,Hibernate 遵循该默认设置。
So Hibernate as well behaves like Ashish Agarwal stated above for JPA:
因此,Hibernate 的行为也类似于上面针对 JPA 所述的 Ashish Agarwal:
OneToMany: LAZY
ManyToOne: EAGER
ManyToMany: LAZY
OneToOne: EAGER
(see JPA 2.1 Spec)
(参见JPA 2.1 规范)
回答by Jijo Mathew
For Single valued associations, i.e.-One-to-One and Many-to-One:-
Default Lazy=proxy
Proxy lazy loading:- This implies a proxy object of your associated entity is loaded. This means that only the id connecting the two entities is loaded for the proxy object of associated entity.
Eg: A and B are two entities with Many to one association. ie: There may be multiple A's for every B. Every object of A will contain a reference of B.
`
对于单值关联,即一对一和多对一:-
默认 Lazy=proxy
代理延迟加载:- 这意味着加载了关联实体的代理对象。这意味着只为关联实体的代理对象加载连接两个实体的 id。
例如:A 和 B 是具有多对一关联的两个实体。即:每个 B 可能有多个 A。A 的每个对象都将包含 B 的引用
。`
public class A{
int aid;
//some other A parameters;
B b;
}
public class B{
int bid;
//some other B parameters;
}
`
The relation A will contain columns(aid,bid,...other columns of entity A).
The relation B will contain columns(bid,...other columns of entity B)
Proxy implies when A is fetched, only id is fetched for B and stored into a proxy object of B which contains only id.
Proxy object of B is a an object of a proxy-class which is a subclass of B with only minimal fields.
Since bid is already part of relation A, it is not necessary to fire a query to get bid from the relation B.
Other attributes of entity B are lazily loaded only when a field other than bid is accessed.
`
关系A 将包含列(aid,bid,...实体A 的其他列)。
关系 B 将包含列(出价,...实体 B 的其他列)
代理意味着当 A 被获取时,只为 B 获取 id 并存储到 B 的代理对象中,该对象只包含 id。B 的代理对象是代理类的对象,代理类是 B 的子类,只有最少的字段。由于出价已经是关系 A 的一部分,因此没有必要触发查询以从关系 B 中获取出价。实体 B 的其他属性仅在访问出价以外的字段时才延迟加载。
For Collections, i.e.-Many-to-Many and One-to-Many:-
Default Lazy=true
Please also note that the fetch strategy(select,join etc) can override lazy.
ie: If lazy='true' and fetch='join', fetching of A will also fetch B or Bs(In case of collections). You can get the reason if you think about it.
Default fetch for single valued association is "join".
Default fetch for collections is "select".
Please verify the last two lines. I have deduced that logically.
对于集合,即多对多和一对多:-
默认 Lazy=true
请注意获取策略(select、join 等)可以覆盖lazy。即:如果lazy='true' 和fetch='join',则获取A 也将获取B 或Bs(在集合的情况下)。如果你仔细想想,你就会明白原因。
单值关联的默认获取是“join”。
集合的默认提取是“选择”。请验证最后两行。我是从逻辑上推断出来的。