Сопоставление типа данных Date с postgress в запросе

У меня проблема, может кто сталкивался, не могу сделать запрос который может корректно работать с null. У меня есть сущность в БД с полем updateAt.

@Data
@Entity
@Accessors(chain = true)
@Table(name = "entity")
@TypeDefs({
        @TypeDef(name = "ENUM", typeClass = PostgreSQLEnumType.class),
        @TypeDef(name = "DURATION", typeClass = PostgreSQLIntervalType.class)
})
public class EntityTypeMetaData implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @UpdateTimestamp
    @Column(name = "updated_at", nullable = false)
    private Date updatedAt;

    @Column(name = "status", nullable = false)
    @Enumerated(EnumType.STRING)
    private TemplateStatus status;

И у меня также есть SQL-запрос, который выбирает все сущности, которые имеют поле updateAt между переданными параметрами, и фильтрует по статусу.

public interface JpaEntityTypeMetadataRepository extends JpaRepository<EntityTypeMetaData,Long> {
 @Query("""
    SELECT em FROM EntityTypeMetaData em
    WHERE (:states IS NULL OR em.status IN :states)
    AND (em.updatedAt BETWEEN :from AND :to)
    """)
    Page<EntityTypeMetaData> findTemplatesByStatusAndUpdatePeriod(
            @Param("states") List<TemplateStatus> states,
            @Param("from") Date from,
            @Param("to") Date to,
            Pageable pageable
    );
}

Здесь у меня идет поиск сущностей из базы данных, у которых поле updateAt находится в переданном диапазоне и в переданных данных статуса. Все это работает правильно, но у меня есть требование проверки на null для параметров from и to. У меня есть такая проверка для параметра states. И если здесь передан null, то эта фильтрация не работает и отображаются все сущности с разными статусами. Но если добавить такую ​​же проверку для полей to и from:

@Query("""
    SELECT em FROM EntityTypeMetaData em
    WHERE (:states IS NULL OR em.status IN :states)
    AND (:from IS NULL OR em.updatedAt >= :from)
    AND (:to IS NULL OR em.updatedAt <= :to)
    """)
Page<EntityTypeMetaData> findTemplatesByStatusAndUpdatePeriod(
        @Param("states") List<TemplateStatus> states,
        @Param("from") Date from,
        @Param("to") Date to,
        Pageable pageable
);

У меня есть исключение 500 в журналах

ERROR: could not determine data type of parameter $3
2024-11-27 14:52:31.427 ERROR [,13c240aa8dcee382,13c240aa8dcee382] 5308 --- [nio-8080-exec-6] r.s.p.sd.handler.SdRestExceptionHandler  : Request with trace id: 13c240aa8dcee382 exception:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet

    Caused by: org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $3
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2675)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2365)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:355)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:490)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:408)

Hibernate не может сделать этот запрос, так как не может определить тип при проверке на null. Он жалуется на третий параметр в запросе, а третий параметр в запросе from, так как первые два это states, это делает некая настройка, которая делает это для скорости выполнения запроса. Но тут суть проблемы в том, что Hibernate не может сделать эту проверку. Может кто-то сталкивался с этим, и может помочь в создании этого запроса с проверкой на null?


Ответы (2 шт):

Автор решения: talex

Попробуй (cast(:from as date) IS NULL OR em.updatedAt >= :from).

→ Ссылка
Автор решения: Artem Boiko

Попробуй (coalesce(:from, em.updateAt) >= :from)

→ Ссылка