#java #spring #hibernate #timestamp #hql
#java #весна #спящий режим #временная метка #hql
Вопрос:
У меня есть Spring Boot API, который использует Spring data JPA (1.5.9) / Hibernate (5.0.12) для запроса моей базы данных PostgreSQL, размещенной на AWS в качестве RDS. Для него установлено значение центрального времени (CST). У меня есть несколько запросов HQL (Hibernate), которые используют эту CURRENT_TIMESTAMP
функцию, но, к сожалению, и, как ни странно, возвращают возвращаемые значения UTC всякий раз, когда выполняются запросы HQL, которые используют CURRENT_TIMESTAMP
run.
Мне нужен способ просто заставить CURRENT_TIMESTAMP
в запросе HQL указывать центральное время (CST). Я пытался просто запросить БД на чистом SQL, и что-то вроде этого сработало:
CURRENT_TIMESTAMP at TIME ZONE 'America/Chicago'
К сожалению, я не могу заставить это работать в HQL, поскольку IntelliJ / Hibernate выдает ошибку компиляции для:
<expression> GROUP, HAVING, or ORDER expected, got 'AT'
Мой пример запроса HQL, который я использую,:
@Query(value = "SELECT customerCoupons FROM CustomerCouponsEntity customerCoupons "
"WHERE customerCoupons.couponCode = :couponCode "
"AND customerCoupons.expiredDate >= CURRENT_TIMESTAMP "
"AND customerCoupons.startDate <= CURRENT TIMESTAMP "
)
List<CustomerCouponsEntity> findByCouponCode(@Param("couponCode") String couponCode);
Любая помощь будет принята с благодарностью. У меня в AWS установлена база данных как CST, поэтому я даже не ожидал, что это CURRENT_TIMESTAMP
вернет значение UTC (по-прежнему не имеет смысла для меня, если только он каким-то образом не использует часовой пояс драйвера JDBC или JVM? Я имею в виду, это запрос в режиме гибернации, так что это не чистый SQL, верно?)
Ответ №1:
Вы должны попытаться установить часовой пояс гибернации в вашем файле свойств загрузки spring. Пример:
spring.jpa.properties.hibernate.jdbc.time_zone=YOUR_TIMEZONE
Убедитесь, что значение YOUR_TIMEZONE соответствует вашему часовому поясу БД.
Я думаю, эта статья поможет
Комментарии:
1. Хорошо, я пытался это сделать (я должен был указать это в своем первоначальном вопросе), но это не сработало. У нас есть более 3 профилей в моем приложении.yaml, но позвольте мне попробовать еще раз, спасибо
2. когда я пытаюсь добавить jdbc.time_zone = UTC в мой проект Spring data JPA / Hibernate, где находятся все мои классы репозитория, это, к сожалению, не влияет на функцию «CURRENT_TIMESTAMP».
3. Кроме того, вы пробовали установить предпочитаемый часовой пояс в своем приложении Spring boot? Я предполагаю, что это повлияет на часовой пояс при создании метки времени с использованием CURRENT_TIMESTAMP.
TimeZone.setDefault(TimeZone.getTimeZone(YOUR_TIMEZONE));
4. Я не пробовал это делать, потому что в статье, на которую вы ссылались, и везде, где я читал, говорилось, что это несет в себе негативные недостатки. Я пробую yaml / properties в течение последних 2 часов и по какой-то причине абсолютно не могу заставить его работать. Я убедился, что нахожусь в режиме гибернации> 5.2.3 и добавлял различные варианты «jdbc.time_zone» и т.д. в свой yaml, но ничего не получалось. Я попробую установить часовой пояс в основном методе SpringBoot сейчас, так как у меня заканчиваются идеи -_- Thx для ответа
5. Я предполагаю, что, несмотря на то, что «В ЧАСОВОМ ПОЯСЕ «Америка / Чикаго»» работает в чистых SQL-запросах, в HQL нет ничего похожего, верно? потому что «AT» даже не является ключевым словом HQL?
Ответ №2:
Публикую свой собственный ответ;
Я попытался установить часовой пояс в properties / yaml в соответствии с этой статьей: https://moelholm.com/blog/2016/11/09/spring-boot-controlling-timezones-with-hibernate
но это не сработало, что бы я ни пробовал. Я убедился, что я в режиме гибернации 5.2.3 или выше, и это не сработает.
Я также попытался добавить «В ЧАСОВОЙ ПОЯС» в свой запрос HQL, но код не компилировался. Я думаю, даже если это допустимый SQL, он не работает с SQL-запросами Hibernate, т.е.
CURRENT_TIMESTAMP at TIME ZONE 'America/Chicago'
В любом случае, единственное, что, казалось, работало, было:
@PostConstruct
void started() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}