HQL左外连接缺少映射

时间:2016-08-04 06:06:14

标签: java sql oracle hql h2db

我正在使用hibernate / hql来创建我的查询。 现在我遇到了一个问题,我现在已经坚持了几个小时,了解这里的情况 我的周围:

我有3张桌子我需要从中获取信息,连接/分配表我总共获得了5个。 我需要的信息是Key,Type和SourceFile,但这里的特例是 sql将在导入新数据时完成,所以我想首先检查数据是否是 已经存在或部分存在。 无论是Type还是SourceFile,我的查询都需要始终给我密钥 如果密钥本身已经在数据库中,那么我只需要密钥而不是其他密钥 信息。 (键匹配但SourceFile和Type没有,所以我只想要键回来) 如果Key存在完全相同的Type和SourceFile,我想获得所有的信息。

表格是:

(抬头:FK_K_ID保存为名称为key的对象,  FK_S_ID保存为Source,FK_T_ID保存为Type)

键:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| K_ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| key         | varchar(255) | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

关键字类型:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| KT_ID       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| FK_K_ID     | bigint(20)   | NO   |     | NULL    |                |
| FK_T_ID     | bigint(20)   | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

类型:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| T_ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| name        | varchar(255) | NO   |     | NULL    |                |
| description | varchar(255) | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

KeySource:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| KS_ID       | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| FK_K_ID     | bigint(20)   | NO   |     | NULL    |                |
| FK_S_ID     | bigint(20)   | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

来源:

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| S_ID        | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| sourceFile  | varchar(255) | NO   |     | NULL    |                |
| deleted     | boolean      | NO   |     | FALSE   |                |
+-------------+--------------+------+-----+---------+----------------+

这是我到目前为止所做的:

from KeyType kt
right outer join kt.Key k
with k.name in (...)
where k.deleted = false
and ( kt.Type in (...) or kt is null )

这个问题是,它有点像我想要的那样。但是我得到了数据库中的所有密钥,只有匹配的KeyType,否则为null。我不想得到所有钥匙,我只想得到我要求的钥匙。

from KeyType kt
right outer join kt.Key k
with k.name in (...)
where k.deleted = false
and (k.name in (...) and kt.Type in (...) or kt is null )

我甚至不知道我在这里试图说实话。我想我试图优化第一个查询只给出我要求的密钥。

from KeyType kt
right outer join fetch kt.Key k
where k.deleted = false
and (k.name in (...) and kt.Type in (...) or kt is null )

我也试过像这样或其他变体使用fetch但是没有像我需要的那样工作。

from Key k
left outer join KeyType kt on kt.Key.id = k.id
left outer join KeySource ks on ks.Key.id = k.id
inner join Source s on ks.Source.id = s.id
where k.deleted = false
and k.name in (...)
and ( kt.appType in (...) or kt is null )
and ( s.SourceFile in (...) or s is null )

正如预期的那样,这不起作用。我的意思是,它很简单,看到它可以工作,但你尝试 很多,如果你不能抓住它。

我尝试了更多的查询组合和变体,但没有运气。第一个查询是我得到的最接近的。 我希望有人可以帮助我。

PS:我现在无法更改地图或实体。我必须和我得到的东西一起工作。

更新:

好吧所以我非常接近解决问题。我的查询现在看起来像这样:

select k, case when kt.Type not in (...) then null
               else 1 end
from KeyType kt
join kt.Key k
where k.name in (...)

现在我唯一要做的就是将1与实际对象交换。但是,如果我这样做,我得到错误" org.hibernate.exception.GenericJDBCException:无法执行查询" (在oracle db上运行)

有人可以告诉我如何解决它吗?

1 个答案:

答案 0 :(得分:0)

对于我的情况和我想要做的事情是不可能的。

所以我再次问同事,我们找到了解决方案,我们必须在单一的查询中做到这一点。

对于那些通过这篇文章配置/问题的人来说,只是说这个。