考虑以下 JPQL 查询:
SELECT foo FROM Foo foo
INNER JOIN FETCH foo.bar bar
WHERE bar.baz = :baz
我正在尝试将其转换为 Criteria 查询。据我所知:
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<Foo, Bar>
似乎没有办法获得 Path
。有什么办法可以避免必须加入两次?或者我必须坚持使用这么简单的查询的旧 JPQL 吗?
原文由 chris 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 JPQL 中,规范中实际上也是如此。 JPA 规范不允许为获取连接指定别名。问题在于,通过限制连接获取的上下文,您可以很容易地搬起石头砸自己的脚。加入两次更安全。
这通常是 ToMany 比 ToOnes 更严重的问题。例如,
这将 错误地 返回所有包含“613”区号中的号码的员工,但会在返回列表中遗漏其他地区的电话号码。这意味着拥有 613 和 416 区号电话的员工将丢失 416 电话号码,因此对象将被损坏。
当然,如果您知道自己在做什么,那么额外的连接是不可取的,一些 JPA 提供程序可能允许别名连接获取,并且可能允许将 Criteria Fetch 转换为连接。