HQL 左外连接缺少映射
HQL left outer join with missing mapping
我正在使用 hibernate/hql 创建我的查询。
现在我遇到了一个问题,我已经坚持了好几个小时,要了解这里的情况是
我的周边:
我有 3 个表需要从中获取信息,connection/assignment 表总共有 5 个。
我需要的信息是密钥、类型和源文件,但这里的特殊情况是
sql 将在导入新数据时完成,所以我想先检查数据是否
已经存在,或部分存在。
我的查询需要始终给我密钥,无论是什么 Type 或 SourceFile
如果密钥本身已经在数据库中,那么我也只想要密钥而不是另一个
信息。 (密钥匹配但 SourceFile 和 Type 不匹配,所以我只想要密钥)
如果密钥存在完全相同的类型和源文件,我想获取所有信息。
表格是:
(注意:FK_K_ID 被保存为一个名为 key 的对象,
FK_S_ID 保存为来源,FK_T_ID 保存为类型)
键:
+-------------+--------------+------+-----+---------+----------------+
| 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 | |
+-------------+--------------+------+-----+---------+----------------+
密钥来源:
+-------------+--------------+------+-----+---------+----------------+
| 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,否则为空。我不想拿到所有钥匙我只想拿到我要的钥匙。
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: could not execute query" (运行 on an oracle db)
有人能告诉我怎么解决吗?
对于我的情况和围绕我想做的方式是不可能的。
所以我再次询问同事,我们得出了我们必须在单个查询中完成的解决方案。
只是对路过此 post 的人说这句话 table configuration/problem.
我正在使用 hibernate/hql 创建我的查询。 现在我遇到了一个问题,我已经坚持了好几个小时,要了解这里的情况是 我的周边:
我有 3 个表需要从中获取信息,connection/assignment 表总共有 5 个。 我需要的信息是密钥、类型和源文件,但这里的特殊情况是 sql 将在导入新数据时完成,所以我想先检查数据是否 已经存在,或部分存在。 我的查询需要始终给我密钥,无论是什么 Type 或 SourceFile 如果密钥本身已经在数据库中,那么我也只想要密钥而不是另一个 信息。 (密钥匹配但 SourceFile 和 Type 不匹配,所以我只想要密钥) 如果密钥存在完全相同的类型和源文件,我想获取所有信息。
表格是:
(注意:FK_K_ID 被保存为一个名为 key 的对象, FK_S_ID 保存为来源,FK_T_ID 保存为类型)
键:
+-------------+--------------+------+-----+---------+----------------+
| 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 | |
+-------------+--------------+------+-----+---------+----------------+
密钥来源:
+-------------+--------------+------+-----+---------+----------------+
| 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,否则为空。我不想拿到所有钥匙我只想拿到我要的钥匙。
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: could not execute query" (运行 on an oracle db)
有人能告诉我怎么解决吗?
对于我的情况和围绕我想做的方式是不可能的。
所以我再次询问同事,我们得出了我们必须在单个查询中完成的解决方案。
只是对路过此 post 的人说这句话 table configuration/problem.