gpt4 book ai didi

hibernate - 为什么 TypedQuery.getResultList() 用单独的 SELECT 解析每个 ManyToOne 关联?

转载 作者:行者123 更新时间:2023-12-03 14:07:37 25 4
gpt4 key购买 nike

考虑以下简单的实体关联:
(实体A)*-1(实体B)
在数据库中使用 EntityA (entityB_id) 中的外键创建。

JPA 实体正在单向映射此关系:

@Entity
EntityA {
@Id
@GeneratedValue
private long id;

@Column(nullable=false,length=250)
private String name;

@ManyToOne(optional=false)
private EntityB entityB;

... getter/setter ...
}

@Entity
EntityB {
@Id
@GeneratedValue
private long id;

@Column(nullable=false,length=250)
private String name;

... getter/setter ...
}

如果进行简单查询:
EntityManager em = ...;
TypedQuery<EntityA> tq = em.createQuery("from EntityA a", EntityA.class);
tq.getResultList();

我在 Hibernate 的 SQL 调试输出中看到,对 EntityA 的每一行都进行了 EntityB 查询:
Hibernate: 
select
entitya0_.id as id8_,
entitya0_.entityB_id as entityB3_8_,
entitya0_.name as name8_
from
EntityA entitya0_
Hibernate:
select
entityb0_.id as id4_0_,
entityb0_.name as name4_0_
from
EntityB entityb0_
where
entityb0_.id=?

即使默认的获取策略是 EAGER(似乎是这种情况),EntityB 也应该通过 implizit join 获取,不是吗?
怎么了?

但它变得更加奇怪——如果只加载了一个 EntityA 对象:
EntityA a = em.find(EntityA.class, new Long(1));

然后 Hibernate 似乎了解这项工作:
Hibernate: 
select
entitya0_.id as id1_1_,
entitya0_.entityB_id as entityB3_1_1_,
entitya0_.name as name1_1_,
entityb1_.id as id12_0_,
entityb1_.name as name12_0_
from
EntityA entitya0_
inner join
EntityB entityb1_
on entitya0_.entityB_id=entityb1_.id
where
entitya0_.id=?

以上测试是使用 Hibernate 3.5 和 JPA 2.0 进行的。

最佳答案

Even if the default fetch strategy is EAGER (which seems to be the case), EntityB should be fetched via implicit join, shouldn't it? What is wrong?



确实,默认 FetchTypeManyToOneEAGER .但这只是说 One侧应该加载 Many侧加载,而不是 怎么样 .如何由持久性提供者自行决定(并且 JPA 不允许调整策略)。

Hibernate 有一个特定的 Fetch注释允许调整获取模式。从文档:

2.4.5.1. Lazy options and fetching modes

JPA comes with the fetch option to define lazy loading and fetching modes, however Hibernate has a much more option set in this area. To fine tune the lazy loading and fetching strategies, some additional annotations have been introduced:

  • [...]

  • @Fetch: defines the fetching strategy used to load the association. FetchMode can be SELECT (a select is triggered when the association needs to be loaded), SUBSELECT (only available for collections, use a subselect strategy - please refers to the Hibernate Reference Documentation for more information) or JOIN (use a SQL JOIN to load the association while loading the owner entity). JOIN overrides any lazy attribute (an association loaded through a JOIN strategy cannot be lazy).



您可能想尝试以下操作(如果您不介意使用提供者特定的注释):
@ManyToOne(optional=false)
@Fetch(FetchMode.JOIN)
private EntityB entityB;

关于hibernate - 为什么 TypedQuery.getResultList() 用单独的 SELECT 解析每个 ManyToOne 关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4156239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com