Java HQL非相关实体的左联接
我有两个实体,Java HQL非相关实体的左联接,java,hibernate,hql,left-join,Java,Hibernate,Hql,Left Join,我有两个实体,A和B。它们是相关的,但我不想将关系映射添加到bean中 如何使用HQL或标准在A和B之间使用左外连接 这方面有一些解决办法 按说明使用本机SQL 添加一个关系并使用从左侧选择一个连接a.b 我们可以在HQL中执行内部联接,作为从a、B中选择*,其中a.some=B.some 我总是回到这两个选项,有没有其他选择?或者这是不可能的?粗体陈述:你不能 为什么??JPQL(和HQL)希望在实体之间有一条路径来连接它们 在这种情况下我通常会做什么(首选顺序): 关联实体 获取以编程方式组
A
和B
。它们是相关的,但我不想将关系映射添加到bean中
如何使用HQL或标准在A
和B
之间使用左外连接
这方面有一些解决办法
我总是回到这两个选项,有没有其他选择?或者这是不可能的?粗体陈述:你不能 为什么??JPQL(和HQL)希望在实体之间有一条路径来连接它们 在这种情况下我通常会做什么(首选顺序):
目前,使用HQL连接where子句中不相关类的theta样式只支持内部连接 在这种情况下支持外部连接的方法是,但是我不认为这个特性会在近期实现,因为它需要第一个,这在IMO看来是一个巨大的任务 如果坚持使用HQL执行左连接而不添加A和B之间的关系,则可以使用选项3首先执行内部连接,然后使用以下HQL
from A a where a.some not in ( select b.some from B)
找出所有不能加入B的A并以编程方式组合结果
更新
从5.1.0版开始是固定的,我们应该能够加入不相关的实体。正如Ken Chan所说,您不能直接在一个HQL查询中完成 关于你的三种可能性:
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 */
...
}
此解决方案在执行时间和内存方面的成本(几乎)与数据库中的外部联接(解决方案2.)相同。这只是多一点java代码
(该解决方案类似于Ken Chan提出的解决方案,但它避免了“不在”和内部选择,这两个选项在数据库中都可能效率低下。)如果您知道每个A最多有1个B,您也可以使用子查询 例如:
select a, (select b from B b where b.some = a.some)
from A a
如果您知道至少存在1个B,您也可以使用以下查询,但不建议使用此查询,因为这是一种黑客行为:
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))
这个答案中的新信息是什么?我在问题中已经提到这些选项,我不想使用它们。期望实体之间有一条路径以便连接它们是错误的。即使没有关联,您也可以进行内部连接。我很抱歉。这就是为什么我说这是一个大胆的声明。我只是想澄清一下。如果你指的是交叉连接,有条件(例如使用两个根)来实现与内部连接相同的事情,那么是的,这是允许的。实际上,加入(Root.join(…)是一种不同的野兽,这就是你需要的,或者HQL等价物,来实现你的目标。到目前为止,我还没有找到解决这个问题的办法。因此我的回答是:你不能。请注意,我很想站在这里!晶莹剔透。谢谢你能指出新的“join on”选项的语法来源吗?我尝试了
从a.x=B.y上的左连接B中选择a,但仍然得到了一个org.hibernate.hql.internal.ast.QuerySyntaxException:连接所需的路径代码>。(我在Maven pom文件中添加了hibernate core
version 5.1.0.Final,其他工件可能在较旧的版本中。但正如我所读到的,这应该足够了。)@Joe7对我来说就是这样。也许你应该运行mvn dependency:tree
来检查旧的hibernate版本,并用
修复它们。哇,非常感谢你。。。这解决了我的问题后,搜索了3天现在!