MySQL / Гибернация: получение значения 1 час при времени типа вставки

#mysql #sql #hibernate #jakarta-ee #time

#mysql #sql #спящий режим #джакарта-ee #время

Вопрос:

Я работаю над веб-проектом Java, который использует:

  • Спящий 5.2.2 режим / JPA 2.0 MySQL5InnoDBDialect

  • MySQL 5.6.15 innoDB (на EasyPHP / phpMyAdmin) JDBC connector 6.0.4

  • Joda time API 2.9.4 Fasterxml jackson API 2.8.3

Я столкнулся с проблемой при вставке Time данных в базу данных. каждый раз, когда я помещаю строку, я получаю значение 1 ЧАС в столбце time!

  • Атрибут на Java :

@JsonFormat(форма=JsonFormat.Форма.СТРОКА, шаблон =»ЧЧ: мм«)
@Столбец (имя = «RES_DUREE», значение null = false)
@Temporal(TemporalType.ВРЕМЯ) повторное заполнение частной даты;

  • Атрибут на SQL :

ВРЕМЯ ВОССТАНОВЛЕНИЯ НЕ равно НУЛЮ;


РЕДАКТИРОВАТЬ (после комментария Адриана Шама):

  • Строка подключения:

jdbc.url = jdbc:mysql://localhost:3306/mydb?useUnicode=trueamp;useJDBCCompliantTimezoneShift=trueamp;useLegacyDatetimeCode=falseamp;serverTimezone=UTC

Я использую UTC, но он по-прежнему составляет 1 час .
Любое предложение поможет, спасибо.

Комментарии:

1. обычно это вызвано несоответствием часового пояса между сервером приложений и базой данных. Вы когда-нибудь пытались отследить фактический SQL, отправленный в БД?

2. Нет, пожалуйста, как я могу это отследить? и почему я это делаю? и спасибо.

3. потому что это дает вам некоторые подсказки о том, какие фактические данные отправляются в БД (и извлекаются). Такие инструменты, как JdbcDsLog (отказ от ответственности, я поддерживаю форк этого в github.com/adrianshum/jdbcdslog ) или аналогичные инструменты будут работать. Хотя в вашей строке подключения указано, что это UTC, находится ли ваш сервер приложений и сам сервер БД в UTC?

4. Да, я думаю, проблема в конфигурации времени сервера. по умолчанию установлено значение Paris вместо UTC. Если вы можете написать ответ, даже теоретический, и упомянуть свой полезный инструмент, возможно, кто-нибудь воспользуется им позже, и мы будем благодарны.

Ответ №1:

Обычно это вызвано несоответствием часовых поясов сервера и базы данных.

Короче говоря, java.util.Date не содержит информации о часовом поясе. Концептуально вы можете рассматривать его как простое представление даты времени (аналогично тому, что делает JODA / JSR310 LocalDateTime ). Поэтому, если ваш сервер приложений UTC 10, а ваша база данных UTC 2, когда вы сохраняете дату «2016-10-13 10:11:12″, хотя ваш сервер приложений обрабатывает ее как «2016-10-13 10:11:12 10:00«, это просто проходит «2016-10-1310:11:12» для DB. Учитывая, что DB равен UTC 2, он считает, что время на самом деле означает «2016-10-13 10:11:12 02:00«. Ситуация становится более запутанной, если утверждается, что ваше соединение JDBC равно «UTC 10», большинство DB будет «умно» переводить «2016-10-13 10:11:12 02:00″ чтобы «2016-10-13 18:11:12 10:00″ что привело к странному хранению и извлечению времени.

Вы можете диагностировать, отслеживая SQL (и фактическое используемое значение) для соответствующих вставок и select. Вы должны увидеть расхождения между значениями и значением, хранящимся в таблице. Такая трассировка может быть выполнена другим способом, например

  1. Более старая версия Hibernate может отображать параметр, используемый в подготовленном операторе, включив соответствующий регистратор
  2. Вы можете использовать такие инструменты, как JdbcDsLog (отказ от ответственности: я сопровождаю форк JbdcDsLog в http://github.com/adrianshum/jdbcdslog )
  3. Вероятно, на стороне СУБД есть инструменты для отслеживания входящих запросов.

Лучший способ решения — убедиться, что все находится в одном часовом поясе, и наиболее рациональным выбором для часового пояса является UTC.