spring-projects / spring-data-jpa

Simplifies the development of creating a JPA-based data access layer.
https://spring.io/projects/spring-data-jpa/
Apache License 2.0
2.92k stars 1.39k forks source link

JPA Query Methods Bug #3493

Closed hyungjlee closed 3 weeks ago

hyungjlee commented 3 weeks ago

Hello.

I think I found a bug while using Spring Data JPA - query methods. I'll attach the code I wrote below, so please check it out.

fun findAllByDcFeePolicyNoAndItemNoIn(dcFeePolicyNo: Long, itemNos: List<String>): List<AutoDcPolicyItemExcptEntity>

I want to use only the AND condition for querying, but when the number of items in the IN clause increases, it seems like an OR condition is being added.

    select
        a1_0.DC_FEE_POLICY_NO,
        a1_0.ITEM_NO
    from
        O_HAN_DISCOUNT.AUTO_DC_POLICY_ITEM_EXCPT a1_0 
    where
        a1_0.DC_FEE_POLICY_NO=? 
        and a1_0.ITEM_NO in(?,?...)
        or a1_0.ITEM_NO in(?,?...)

When I check the logs for the actual queries being executed, I can see that the OR condition is being appended. This is causing unintended results to be displayed.

It seems like this problem occurs because of the number of items in the IN clause. When the number exceeds a certain limit (probably 1000?), it seems to split the query with OR conditions. It looks like the query needs to be modified by adding parentheses for proper separation. Alternatively, it would be fine to throw an exception if the number exceeds 1000.

here is the version I am using. spring-data-jpa:3.0.10 spring-boot:3.0.11 kotlin 1.9.10

Please check it out. Thanks.

mp911de commented 3 weeks ago

Spring Data JPA doesn't generate any SQL statements, you might want to create a criteria query yourself with the given query and introspect whether the same SQL is being generated. AND has a higher precedence, partitioning IN clauses isn't unusual.

quaff commented 3 weeks ago

@hyungjlee It's fixed by https://github.com/hibernate/hibernate-orm/commit/1cc94c76b9ede65001923b9611208996222a1ad3, you should upgrade your Hibernate version.