fix(audit): sentinel timestamps вместо :from IS NULL в JPQL

PostgreSQL не может вывести тип параметра OffsetDateTime когда оба боковых
выражения IS NULL ⇒ 500 на /api/v1/admin/audit. Фикс — controller подставляет
0001-01-01/9999-12-31 если from/to не указаны, JPQL использует обычное
сравнение eventTime BETWEEN :from AND :to. Строковые фильтры (dictionary,
user, action, businessKey) остаются с :p IS NULL OR x = :p — они работают
потому что VARCHAR PG может вывести из правой стороны сравнения.
This commit is contained in:
Zimin A.N.
2026-05-04 16:02:03 +03:00
parent 5ffb51e119
commit 2a82e0d6a3
2 changed files with 10 additions and 6 deletions
@@ -23,6 +23,10 @@ public interface AuditLogRepository extends JpaRepository<AuditLog, Long> {
/**
* Гибкий запрос для admin UI: фильтры nullable, NULL = «не фильтруем».
* Сортировка задаётся {@link Pageable}.
*
* <p>Для {@code from}/{@code to} (OffsetDateTime) NULL не передаём — PostgreSQL не
* может вывести тип параметра из {@code IS NULL} проверки. Вместо этого
* controller подставляет {@link OffsetDateTime#MIN} / {@link OffsetDateTime#MAX}.
*/
@Query("""
SELECT a FROM AuditLog a
@@ -30,8 +34,8 @@ public interface AuditLogRepository extends JpaRepository<AuditLog, Long> {
AND (:userId IS NULL OR a.userId = :userId)
AND (:action IS NULL OR a.action = :action)
AND (:businessKey IS NULL OR a.businessKey = :businessKey)
AND (:from IS NULL OR a.eventTime >= :from)
AND (:to IS NULL OR a.eventTime <= :to)
AND a.eventTime >= :from
AND a.eventTime <= :to
""")
Page<AuditLog> search(
@Param("dictionaryName") String dictionaryName,