2016-08-04 65 views
0

我使用hibernate/hql来创建我的查询。 现在我有一个问题,我被困在相当长的一段时间,现在,了解这里的情况是 我sorrounding:HQL左外连接缺失映射

我有3桌,我需要从中获取信息,与连接/分配表我5总体。 我需要的信息是Key,Type和SourceFile,但这里的特例是 sql会在导入新数据时完成,所以我想先检查数据是否为 已存在或部分存在。 我的查询需要总是给我的密钥,无论是什么类型或SourceFile 如果密钥本身已经在数据库中,我也只需要密钥而不是其他 信息。 (密钥匹配,但SourceFile和类型不,所以我只想回密钥) 如果密钥存在与完全相同的Type和SourceFile我想获取所有信息。

的表是:

(抬头:FK_K_ID保存为名为密钥的对象, 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 |    | 
+-------------+--------------+------+-----+---------+----------------+ 

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) 

我也尝试使用像这样或其他变化的抓取,但没有像我需要的那样工作。

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数据库上运行)

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

回答

0

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

所以我再次问同事,我们来到解决方案,我们必须做单查询。

只是对任何人通过这篇文章与相同的表配置/问题说这个。