I am using hibernate/hql to create my querys. Now I got a problem I'm stuck on for quite some hours now, to understand the situation here is my sorrounding:
I got 3 Tables I need to get Informations from, with the connection/assignment tables I got 5 overall. The Informations I need are the Key, the Type and the SourceFile, but the special case here is that the sql will be done while importing new data, so I want to first check if the data is already existent, or partially existent. My query needs to always give me the key, no matter what Type or SourceFile if the Key itself is already in the Database, also I then only want the key and not the other Informations. (Key matches but SourceFile and Type do not, so I want only the key back) If the Key is existent with the exact same Type and SourceFile I want to get all Informations.
The Tables are:
(heads up: FK_K_ID is saved as a object with the name key, FK_S_ID is saved as Source and FK_T_ID is saved as Type)
Key:
+-------------+--------------+------+-----+---------+----------------+
| 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 | |
+-------------+--------------+------+-----+---------+----------------+
Type:
+-------------+--------------+------+-----+---------+----------------+
| 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 | |
+-------------+--------------+------+-----+---------+----------------+
Source:
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| S_ID | bigint(20) | NO | PRI | NULL | auto_increment |
| sourceFile | varchar(255) | NO | | NULL | |
| deleted | boolean | NO | | FALSE | |
+-------------+--------------+------+-----+---------+----------------+
and here is what I tried so far:
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 )
The problem with this one is, it kind of does what I want. but I get all keys in the database and the KeyType only where it matches, else null. I don't want to get all keys I just want to get my keys I asked for.
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 )
I don't even know what I tried here to be honest. I guess I tried to optimize the first query to only give the keys I asked for.
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 )
I also tried to use fetch like this or in other variations but didn't work like I need it to.
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 )
well as expected this doesn't work. I mean its quite simpel to see that it can't work but you try a lot if you can't get a hang on it.
I tried many more combinations and variations of querys but with no luck. The first query is the closest I got. I Hope somebody can help me.
PS: I can't change the mapping or the entitys now. I have to work with what I got.
UPDATE:
Alright so I am very close to solving the problem. My query now looks like this:
select k, case when kt.Type not in (...) then null
else 1 end
from KeyType kt
join kt.Key k
where k.name in (...)
Now the only thing I want to to is exchange the 1 with the actual object. But if I do this I get the error "org.hibernate.exception.GenericJDBCException: could not execute query" (running on an oracle db)
Can someone tell me how to solve it?
For my case and sorrounding the way I wanted to do it is not possible.
So I asked coworkers again and we came to the solution we have to do it in single querys.
Just saying this for anyone passing by this post with the same table configuration/problem.