Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

in produces malformed query when called with an empty collection #702

Closed
szanyierik opened this issue May 2, 2024 · 2 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@szanyierik
Copy link

Example code:

interface EmployeeRepository : JpaRepository<Employee, String>, KotlinJdslJpqlExecutor {
}
employeeRepository.findAll {
    select(entity(Employee::class))
        .from(entity(Employee::class))
        .where(path(Employee::id).`in`(ids))
}

When ids is a non-empty collection, the query is rendered correctly:

SELECT Employee FROM Employee AS Employee WHERE Employee.id IN (:param1){param1=asd}

However, when ids is an empty collection, the produced query is malformed (empty WHERE clause):

SELECT Employee FROM Employee AS Employee WHERE {}

This is probably a result of how JpqlIn is serialized - when compareValues is empty, the serializer just returns without doing anything, resulting in a malformed query.

For reference, Hibernate deals with similar situations by replacing the IN predicate with 1=0. For example,

@Query(
    """
        SELECT e FROM Employee AS e
        WHERE e.id IN :ids
    """
)
fun findAllEmployeesById(ids: Collection<String>): List<Employee>

turns into

select
    e1_0.id,
    e1_0.name
from
    employee e1_0 
where
    1=0

when ids is an empty collection.

This bug has already been reported here, but I was requested to create a new issue.

@shouwn shouwn self-assigned this May 2, 2024
@shouwn shouwn added the bug Something isn't working label May 2, 2024
@kshired
Copy link
Contributor

kshired commented May 3, 2024

There's some difference between Jpa Query Method and @Query annotation.

interface ExampleRepository: JpaRepository<ExampleEntity, Long> {
    fun findAllByIdIn(ids: List<Long>): List<ExampleEntity>
    fun findAllByIdNotIn(ids: List<Long>): List<ExampleEntity>

    @Query("select e from ExampleEntity e where e.id in :ids")
    fun findAllByIdInCustom(ids: List<Long>): List<ExampleEntity>

    @Query("select e from ExampleEntity e where e.id not in :ids")
    fun findAllByIdNotInCustom(ids: List<Long>): List<ExampleEntity>
}

exampleRepository.findAllByIdIn(emptyList())
exampleRepository.findAllByIdNotIn(emptyList())
exampleRepository.findAllByIdInCustom(emptyList())
exampleRepository.findAllByIdNotInCustom(emptyList())

As a result of the above code, the SQL is generated as below.

select e1_0.id, e1_0.name from example e1_0 where e1_0.id in (NULL); -- findAllByIdIn
select e1_0.id, e1_0.name from example e1_0 where e1_0.id not in (NULL); -- findAllByIdNotIn
select e1_0.id, e1_0.name from example e1_0 where 1=0; -- findAllByIdInCustom
select e1_0.id, e1_0.name from example e1_0 where 1=0; -- findAllByIdNotInCustom

But since either in (NULL) or not in (NULL) is false in the end, I think it doesn't matter much.

@shouwn
Copy link
Member

shouwn commented May 5, 2024

I deployed the 3.4.1 hotfix, please reopen this issue if you have similar issues.

@shouwn shouwn closed this as completed May 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants