如何正确表达JPQL“join fetch"用“哪里"条款作为 JPA 2 CriteriaQuery? [英] How to properly express JPQL "join fetch" with "where" clause as JPA 2 CriteriaQuery?

查看:33
本文介绍了如何正确表达JPQL“join fetch"用“哪里"条款作为 JPA 2 CriteriaQuery?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下 JPQL 查询:

Consider the following JPQL query:

SELECT foo FROM Foo foo
INNER JOIN FETCH foo.bar bar
WHERE bar.baz = :baz

我正在尝试将其转换为 Criteria 查询.这是我得到的:

I'm trying to translate this into a Criteria query. This is as far as I have gotten:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class);
Root<Foo> r = cq.from(Foo.class);
Fetch<Foo, Bar> fetch = r.fetch(Foo_.bar, JoinType.INNER);
Join<Foo, Bar> join = r.join(Foo_.bar, JoinType.INNER);
cq.where(cb.equal(join.get(Bar_.baz), value);

这里明显的问题是我做了两次相同的连接,因为 Fetch 似乎没有获取 Path 的方法.有没有办法避免必须加入两次?或者我是否必须坚持使用旧的 JPQL 进行如此简单的查询?

The obvious problem here is that I am doing the same join twice, because Fetch<Foo, Bar> doesn't seem to have a method to get a Path. Is there any way to avoid having to join twice? Or do I have to stick with good old JPQL with a query as simple as that?

推荐答案

在 JPQL 中,规范中实际上也是如此.JPA 规范不允许为获取连接指定别名.问题是您可以通过限制连接提取的上下文轻松地用这个来射击自己.加入两次更安全.

In JPQL the same is actually true in the spec. The JPA spec does not allow an alias to be given to a fetch join. The issue is that you can easily shoot yourself in the foot with this by restricting the context of the join fetch. It is safer to join twice.

这通常是 ToMany 的问题,而不是 ToOnes.例如,

This is normally more an issue with ToMany than ToOnes. For example,

Select e from Employee e 
join fetch e.phones p 
where p.areaCode = '613'

这将错误地返回所有在613"区号中包含号码的员工,但会在返回的列表中遗漏其他地区的电话号码.这意味着拥有 613 和 416 区号电话号码的员工将丢失 416 电话号码,因此该对象将被损坏.

This will incorrectly return all Employees that contain numbers in the '613' area code but will left out phone numbers of other areas in the returned list. This means that an employee that had a phone in the 613 and 416 area codes will loose the 416 phone number, so the object will be corrupted.

当然,如果您知道自己在做什么,额外的连接是不可取的,一些 JPA 提供程序可能允许别名连接提取,并可能允许将标准提取转换为连接.

Granted, if you know what you are doing, the extra join is not desirable, some JPA providers may allow aliasing the join fetch, and may allow casting the Criteria Fetch to a Join.

这篇关于如何正确表达JPQL“join fetch"用“哪里"条款作为 JPA 2 CriteriaQuery?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆