Search code examples
javaspringspring-boothibernatejpa

NULLS FIRST/LAST override no longer works in JPA repositories in Spring Boot 3/Hibernate 6


In Spring Boot 2 with Hibernate 5 we had a query like this:

@Query("""
    SELECT m FROM ProjectMember m
    ORDER BY m.lastActive ASC NULLS LAST
    """)
List<ProjectMember> sortLastActiveDesc();

(defined in a class public interface ProjectMemberRepository extends JpaRepository<ProjectMember, UUID> {)

This query is slightly trimmed down from the real one just to have a small reproduction case.

This is needed because we need to override how nulls are sorted. The underlying database here is PostgreSQL.

However, in Spring Boot 3.1.0 with Hibernate 6, this no longer works. The application will start and does not throw an exception on startup, but when executing this query it will throw this exception:

org.springframework.dao.InvalidDataAccessApiUsageException
...
... (huge stack trace here)
...
Caused by: org.springframework.data.jpa.repository.query.BadJpqlGrammarException: Line 2:26 mismatched input 'NULLS' expecting {<EOF>, ',', EXCEPT, FETCH, INTERSECT, LIMIT, OFFSET, UNION}; Bad JPQL grammar [select m from ProjectMember m
ORDER BY m.lastActive ASC NULLS FIRST
]
    at org.springframework.data.jpa.repository.query.BadJpqlGrammarErrorListener.syntaxError(BadJpqlGrammarErrorListener.java:39)
    at org.antlr.v4.runtime.ProxyErrorListener.syntaxError(ProxyErrorListener.java:41)

How is this supposed to work from now on, without having to fall back to native SQL?

(Note I have also tried setting the null handling property using sort = Sort.by(new Sort.Order(Direction.ASC, "lastActive", NullHandling.NULLS_FIRST)); and then passing a Pageable to the repository method and then not defining the ordering by myself, but looking at the generated SQL the null ordering seems to be completely ignored)


Solution

  • As was commented on my question, it's merely a bug that is being fixed in Spring Boot 3.1.1: https://github.com/spring-projects/spring-data-jpa/issues/2962