We would like to left outer join two tables in HQL using two columns for the join.
The second column for the join has no relevance at the logical level and doesn't restrict the result set in any way. It's the partition key and is used solely as an optimization to speed up the phyiscal data access.
In SQL it would be something like
select *
from t1
left outer join t2
on t1.id = t2.parent_id
and t1.partion_key = t2.partition_key
The following approaches that we tried didn't work:
-
We can do an outer join in HQL
left join fetch
and it's possible to specify an additional condition in the join usingwith
but both can't be combined together. This limitation is explicitely mentioned in the documentation:
"Fetch should also not be used together with impromptu with condition". -
Using an additional where condition
t1.partion_key = t2.partition_key
doesn't work because it change the semantics of the query from an outer join to an inner join: when no data matches the condition doesn't hold and the row is ignored. -
Using the oracle syntax
t1.partion_key = t2.partition_key (+)
also doesn't work since it results in a SQL query that mixes the ANSI und Oracle syntax. -
We though about using a combined key but it's not really correct because at the logical level, the key is only
id
. We don't want to let the physical data modelling (partitioning) impact the logical model.
How can we express the desired query with HQL?
Best Answer
1) Since Hibernate 5.1 we can use 'join' on unrelated classes in HQL queries. In this case we can use this HQL query:
2) Another approach is to modify entities as following (adding two
JoinColumn
s tochildren
property inParent
entity and replacingparent
'many-to-one' relation to simpleparentId
property inChild
entity):Then we can use the following simple JPQL query:
Both queries are translated by Hibernate to like this SQL query:
Working demo is here.