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:
+6
-2
@@ -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,
|
||||
|
||||
+4
-4
@@ -52,8 +52,8 @@ public class AuditAdminController {
|
||||
nullIfBlank(userId),
|
||||
nullIfBlank(action),
|
||||
nullIfBlank(businessKey),
|
||||
from,
|
||||
to,
|
||||
from == null ? OffsetDateTime.parse("0001-01-01T00:00:00Z") : from,
|
||||
to == null ? OffsetDateTime.parse("9999-12-31T23:59:59Z") : to,
|
||||
PageRequest.of(page, Math.min(size, 200), Sort.by(Sort.Direction.DESC, "eventTime")));
|
||||
return result.map(AuditEntry::from);
|
||||
}
|
||||
@@ -71,8 +71,8 @@ public class AuditAdminController {
|
||||
nullIfBlank(userId),
|
||||
nullIfBlank(action),
|
||||
nullIfBlank(businessKey),
|
||||
from,
|
||||
to,
|
||||
from == null ? OffsetDateTime.parse("0001-01-01T00:00:00Z") : from,
|
||||
to == null ? OffsetDateTime.parse("9999-12-31T23:59:59Z") : to,
|
||||
PageRequest.of(0, MAX_EXPORT_ROWS, Sort.by(Sort.Direction.DESC, "eventTime")));
|
||||
|
||||
StringBuilder csv = new StringBuilder(
|
||||
|
||||
Reference in New Issue
Block a user