HQL留下了非关联实体的连接

我有两个实体, AB 他们是相关的,但我不想将关系映射添加到豆。

我们如何使用HQL或条件使用AB之间A左外连接

有一些解决方法可用于此,

  1. 按照此处所述使用Native SQL。
  2. 添加一个关系并使用从A中select一个左连接ab
  3. 我们可以在HQL中做一个内部连接 select * from A a,B b where a.some = b.some

我总是回去这两个选项,有没有其他的select呢? 或者这在不可能?

目前,使用HQLjoinwhere子句中无关类的theta样式只支持内连接。

支持这种情况的外连接的请求 目前是第三次投票增强,但我不认为这个特性将在近端特性中实现,因为它需要首先重新实现当前的基于ANTLER的查询parsing器这似乎是IMO的一个巨大的任务。

如果您坚持使用HQL来执行左连接而不添加A和B之间的关系,则可以使用选项3先执行内连接,然后使用以下HQL

 from A a where a.some not in ( select b.some from B) 

找出所有不能joinB的A,并以编程方式结合结果。

更新

从版本5.1.0开始, HHH-16(对不相关类的显式连接)是固定的,我们应该能够join不相关的实体。

正如Ken Chan所说,你不能直接在一个HQL查询中完成。

关于你的三种可能性:

  1. 原生SQL:不推荐。 外连接的语法在不同的数据库之间是完全不同的。
  2. 添加一个关系:这就是我会做的。 它不会花费太多的代码或内存,并且可以快速编程。
  3. 内部连接:如果关系确实是数据库中的外部连接,则不起作用(缺less行)。

如果由于任何特殊的原因你不想添加关系,你可以将查询拆分为两个单独的查询,并在java中手动join结果,例如:

 Query qa = session.createQuery("from A a"); List la = qa.list(); Query qb = session.createQuery("select distinct b.* from B b, A a where a.some=b.some"); List lb = qb.list(); Map bMap = new HashMap(); for (B b : lb) { bMap.put(b.getId(), b); } /* example with for loop */ for (A a : la) { B b = bMap.get(a.getForeignKeyForB()); /* now you have A a and the outer joined B b and you can do with them what you want */ ... } 

该解决scheme在执行时间和内存方面与数据库中的外连接(解决scheme2)具有(几乎)相同的成本。 这只是一个更多的Java代码。

(该解决scheme与Ken Chan提出的解决scheme类似,但是避免了“不在”和内部select,这两者在数据库中都是低效的)。

大胆的声明:你不能。

为什么? JPQL(和HQL)期望实体之间的path,以join它们。

我通常在这样的情况下做的(首选):

  1. 关联实体。
  2. 获取您需要的数据以编程方式组装结果。
  3. 您已经提到的三个选项中的一个或三个。

如果你知道每个A有最多1 B,你也可以使用子查询。

例如:

 select a, (select b from B b where b.some = a.some) from A a 

如果您知道至less存在1 B,则也可以使用以下查询,但不build议这样做,因为它是黑客行为:

 select a, (select b4 from B b4 where b4=b and b4.some=a.some) from A a, B b where a.some=b.some or (a.some not in (select b2.some from B b2) and b.id = (select min(b3.id) from B b3))