gpt4 book ai didi

hibernate - 如何避免 HQL 和 Criteria 中不必要的选择和连接

转载 作者:行者123 更新时间:2023-12-03 15:52:28 25 4
gpt4 key购买 nike

我一直在尝试 的不同组合HQL 标准 我无法避免一些不必要的加入 (在两者中)和一些不必要的 选择 (在标准中)。

在我们的场景中,我们有一个 @ManyToMany 之间的关系分割申请实体(导航是从 Segment 到 Applications)。

首先我尝试了这个 标准 :

Application app = ...
List<Segment> segments = session.createCriteria(Segment.class)
.createCriteria(Segment.APPLICATIONS)
.add(Restrictions.idEq(app.getId()))
.list();

Wich 生成此 SQL:
select
this_.id as id1_1_,
this_.description as descript2_1_1_,
this_.name as name1_1_,
applicatio3_.segment_id as segment1_1_,
applicatio1_.id as app2_, <==== unnecessary APPLICATIONS columns
applicatio1_.id as id7_0_,
applicatio1_.name as name7_0_,
applicatio1_.accountId as accountId7_0_,
applicatio1_.applicationFlags as applicat5_7_0_,
applicatio1_.description_ as descript6_7_0_,
from
SEGMENTS this_
inner join
SEGMENTS_APPLICATIONS applicatio3_
on this_.id=applicatio3_.segment_id
inner join <==== unnecessary join
APPLICATIONS applicatio1_
on applicatio3_.app_id=applicatio1_.id
where
applicatio1_.id = ?

如您所见,Criteria 从 APPLICATIONS 中选择列,我不想选择这些列。我还没有找到一种方法来做到这一点(可能吗?)。此外,它与 APPLICATIONS 连接,我认为这不是必需的,因为应用程序 ID 已经在连接表 SEGMENTS_APPLICATIONS 中(HQL 也是如此)。

(另外一个疑问,我想知道一个直接使用应用程序的限制,而不是 app.getId()。如您所见,我可以在查询的 HQL 版本中做到这一点)

由于我无法限制选择部分(我不需要应用程序属性),我尝试了这个 HQL 使用“选择”子句:
Application app = ...
List<Segment> segments = session.createQuery(
"select s from Segment s join s.applications as app where app = :app")
.setParameter("app", app)
.list();

产生:
select
segment0_.id as id1_,
segment0_.description as descript2_1_,
segment0_.name as name1_,
from
SEGMENTS segment0_
inner join
SEGMENTS_APPLICATIONS applicatio1_
on segment0_.id=applicatio1_.segment_id
inner join <==== unnecessary join
APPLICATIONS applicatio2_
on applicatio1_.app_id=applicatio2_.id
where
applicatio2_.id=?

你可以看到 HQL 没有从 Application 中选择属性(感谢“select s”部分),但仍然加入了 APPLICATIONS 表,我认为这是不必要的。我们怎样才能避免这种情况?

(作为旁注,请注意在 HQL 中我可以直接使用 app,而不是像 Criteria 中那样的 app.getId())

你能帮我找到一种方法来避免标准中的“选择”和标准和 HQL 中不必要的“连接”吗?

(这个例子是@ManyToMany,但我认为@OneToMany、@ManyToOne 和@OneToOne 也会发生这种情况,即使是 fetch = LAZY)。

非常感谢,
费兰

最佳答案

使用 Criteria 时额外选择的列来自长期存在的 bug in Hibernate . AFAIK,避免它的唯一方法是使用 HQL 或 JPA2 标准 API。

另一个问题也被标记为 a bug ,但它的影响较小,我不会太在意。

关于hibernate - 如何避免 HQL 和 Criteria 中不必要的选择和连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10665084/

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