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

Spring Data JPA 3.3.0 generates incorrect condition for WHERE clause #3509

Closed opera-romanso closed 2 weeks ago

opera-romanso commented 2 weeks ago

We upgraded the version from 3.2.4 to 3.3.0. When executing repository methods such as

@Query("""
      SELECT a.field1, a.field2
        FROM Object a
       WHERE a.objectId IN :someIds
         AND a.object2.current_state = 'some_value'""")
List<SomeProjection> findProjectionBySomeIdIn(Collection<String> someIds);

with an empty collection as a parameter, we realized that the following code is generated: (version 3.3.0)

...
where
  (1 = case when av1_0.object_id is not null then 0 end)
  and (c1.current_state_1 = 'some_value')

with execution plan:

Hash Join  (cost=16.36..521.31 rows=14 width=421)
  Hash Cond: (av1_0.configuration_id = c1_0.configuration_id)
  ->  Nested Loop  (cost=0.29..505.20 rows=14 width=253)
        ->  Seq Scan on objects av1_0  (cost=0.00..234.53 rows=35 width=109)
              Filter: (1 = CASE WHEN (objects_id IS NOT NULL) THEN 0 ELSE NULL::integer END)
        ->  Index Scan using objects_pkey on objects a1_0  (cost=0.29..7.73 rows=1 width=181)
              Index Cond: (object_id = av1_0.objects_id)
              Filter: (current_state = 'some_value'::text)
  ->  Hash  (cost=12.70..12.70 rows=270 width=200)
        ->  Seq Scan on objects2 c1_0  (cost=0.00..12.70 rows=270 width=200)

instead of (version 3.2.4)

...
where
  1 = 0
  and (c1.current_state_1 = 'some_value')

with execution plan:

Result  (cost=0.00..0.00 rows=0 width=421)
  One-Time Filter: false

I didn't find any changes in the Spring Data changelog that would indicate a behavior change. Is this behavior intentional or is this an issue in 3.3.0?

quaff commented 2 weeks ago

I believe the regression is introduced by https://hibernate.atlassian.net/browse/HHH-17804 at Hibernate side and reverted by https://hibernate.atlassian.net/browse/HHH-18241 in 6.5.3 which is not release for now.

opera-romanso commented 2 weeks ago

Oh, it’s great news, thanks! Then, I guess ticket can be closed.

schauder commented 2 weeks ago

Thanks for linking this to the Hibernate issue.