2016-08-04 2 views
0

Я использую hibernate/hql для создания моих запросов. Теперь У меня проблема, я застрял в течение достаточно долгого часов в настоящее время, чтобы понять ситуацию здесь является мой sorrounding:HQL left external join with missing mapping

Я получил 3 таблицы, мне нужно, чтобы получить Informations из, с таблицами подключения/назначения я получил 5 в целом. Информация, которая мне нужна, - это ключ, тип и исходный файл, но особый случай: , что sql будет выполнен при импорте новых данных, поэтому я хочу сначала проверить, есть ли данные уже существующих или частично существующих , Мой запрос должен всегда давать мне ключ, независимо от типа или исходного файла , если сам ключ уже находится в базе данных, также мне нужен только ключ, а не другой Информация. (Ключевых совпадений, кроме SourceFile и Type, нет, поэтому я хочу только вернуть ключ) Если ключ существует с тем же типом и исходным файлом, я хочу получить всю информацию.

Таблицы:

(головы до: 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 |    | 
+-------------+--------------+------+-----+---------+----------------+ 

KeyType:

+-------------+--------------+------+-----+---------+----------------+ 
| 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: Я не могу изменить отображение или сущности сейчас.Мне нужно работать с тем, что у меня есть.

UPDATE:

Хорошо, так что я очень близко к решению этой проблемы. Теперь мой запрос выглядит так:

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)

Может ли кто-нибудь сказать мне, как его решить?

ответ

0

Для моего случая и вокруг того, как я хотел это сделать, это невозможно.

Так что я снова спросил сотрудников, и мы пришли к решению, которое мы должны сделать в одном запросе.

Просто скажите это всем, кто проходит мимо этого сообщения с той же конфигурацией/проблемой таблицы.

Смежные вопросы