Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate Java rearranging parentheses in SQL

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.

like image 554
trix Avatar asked May 20 '14 11:05

trix


2 Answers

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).

like image 116
Murthy Avatar answered Oct 10 '22 05:10

Murthy


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

like image 23
trix Avatar answered Oct 10 '22 03:10

trix