Есть Entity с полем типа Instant:
@Entity
public class SomeEntity {
@Id
private Long id;
@Column(nullable = false)
private Instant testValue;
}
В PostgreSQL есть таблица с полями:
{id: BIGINT, testValue: TIMESTAMP}
Файл application.yml содержит:
spring.jpa.properties.hibernate.jdbc.time_zone: UTC
Пример тестового репозитория JPA, который демонстрирует суть проблемы. Результат не зависит от функции: CURRENT_TIMESTAMP, CURRENT_TIMESTAMP(), NOW().
public interface SomeEntityRepository extends JpaRepository<SomeEntity, Long> {
@Query("SELECT s.testValue, NOW(), s.testValue > NOW() FROM SomeEntity s WHERE s.id = 1")
@NonNull
List<SomeEntity> testFind();
}
Например имеем системное время 2022-06-07 07:00:00 и часовой пояс UTC+2:
1.
System.out.println(Instant.now()) выдает
2022-06-07 05:00:00.000000000Z это правильно.
2. Сохранение объекта
{id: 1, testValue: Instant.now().plus(30, ChronoUnit.MINUTES)} в БД дает ожидаемый результат
{id: 1, testValue: 2022-06-07 05:30:00.000000}
3. Если я вызываю someEntityRepository.testFind() то получаю: java.time.Instant (2022-06-07 05:30:00.000000000Z), java.sql.Timestamp (2022-06-07 07:00:00.0000000),
false (это не то, что я ожидаю).
Получается что в результате каких-то преобразований итог следующий:
java.time.Instant (2022-06-07 05:30:00.000000000Z) < java.sql.Timestamp (2022-06-07 07:00:00.0000000)
.
А я предполагал увидеть следующий результат:
java.time.Instant (2022-06-07 05:30:00.000000000Z) > java.time.Instant (2022-06-07 05:00:00.000000000Z) == java.sql.Timestamp (2022-06-07 07:00:00.0000000)
Что не так в моем подходе? Мне нужно не использовать Instant или я пропустил где-то настройку?
Мне нужно хранить в БД даты в UTC и при этом иметь возможность сравнивать их с NOW().
Я вышел из положения пробрасыванием Instant.now() в качестве параметра, используя его как
:now.