I've got a @NamedQuery
like so
select i from MyTable i
where
(i.streetId = :streetId and i.cityId = :cityId)
or
(i.streetId is null and i.cityId = :cityId)
or
(i.streetId = :streetId and i.cityId is null)
Somehow Hibernate rearranges the parentheses to
Hibernate:
select
mytable0_.id as id1_14_,
mytable0_.version as version2_14_,
mytable0_.streetId as streetI3_14_,
mytable0_.cityId as cityId7_14_
from
myTable mytable0_
where
mytable0_.streetId=?
and mytable0_.cityId=?
or (
mytable0_.streetId is null
)
and mytable0_.cityId=?
or mytable0_.streetId=?
and (
mytable0_.cityId is null
)
Why is it doing this ? (They could be equivalent, but I prefer the simpler where clause)
Current workaround is to write this in native SQL, but I'm just wondering if this is a known issue.
Since 'AND' operation has higher precedence over 'OR' operation in SQL Query execution, hibernate removed unnecessary braces, making the result generated by hiberante query is same as one returned by Named Query. Ex: In SQL Execution:
A and B or C and D or E and F == (A and B) or (C and D) or (E and F).
Guided by the responses this is what I figured out
Imagine
A is streetId = :streetId
B is cityId = :cityId
C is streetId is null
D is cityId is null
My original SQL is
(A and B) or (C and B) or (A and D)
Hibernate's version is
A and B or (C) and B or A and (D)
Since AND has precedence over OR, let's reimagined using MULTIPLICATION for AND and ADDITION for OR
A * B + (C) * B + A * (D)
That's equivalent to
A * B gets evaluated
C * B gets evaluated
A * D gets evaluated
and getting their results added
Equivalent to (A * B) + (C * B) + (A * D)
Which is exactly my original SQL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With