Hibernate @CreationTimestamp @UpdateTimestamp в разных часовых поясах - PullRequest
0 голосов
/ 04 октября 2019

Использование ниже двух для хранения времени обновления и создания.

@CreationTimestamp
private Timestamp creationTime;

@UpdateTimestamp
private Timestamp updationTime;

Когда я создаю новую запись, обе они хранятся в часовом поясе UTC.

+------------+----------------------------------+--------------+--------------+--------------------+--------------------+-----------------------+---------------------------+------+-------------------+---------------------+------------+------------+---------------------+---------------------+----------+
| meeting_id | analysis_description             | meeting_date | preread_date | first_version_date | reminder_sent_date | review_addressed_date | review_comments_addressed | tfls | first_record_flag | current_record_flag | created_by | updated_by | creation_time       | updation_time       | end_time |
+------------+----------------------------------+--------------+--------------+--------------------+--------------------+-----------------------+---------------------------+------+-------------------+---------------------+------------+------------+---------------------+---------------------+----------+
|          4 | BAF312A2122 - CRT 1 - LEGACY CRT | NULL         | NULL         | NULL               | NULL               | NULL                  | NULL                      |    0 | Y                 | Y                   | NULL       | NULL       | 2019-10-04 06:36:36 | 2019-10-04 06:36:36 | NULL     |
+------------+----------------------------------+--------------+--------------+--------------------+--------------------+-----------------------+---------------------------+------+-------------------+---------------------+------------+------------+---------------------+---------------------+----------+
1 row in set (0.00 sec)  

Однако, если я обновлю запись, метка времени создания изменится на мою локальную метку времени.

+------------+----------------------------------+--------------+--------------+--------------------+--------------------+-----------------------+---------------------------+------+-------------------+---------------------+------------+------------+---------------------+---------------------+----------+
| meeting_id | analysis_description             | meeting_date | preread_date | first_version_date | reminder_sent_date | review_addressed_date | review_comments_addressed | tfls | first_record_flag | current_record_flag | created_by | updated_by | creation_time       | updation_time       | end_time |
+------------+----------------------------------+--------------+--------------+--------------------+--------------------+-----------------------+---------------------------+------+-------------------+---------------------+------------+------------+---------------------+---------------------+----------+
|          4 | BAF312A2122 - CRT 1 - LEGACY CRT | 2019-09-30   | 2019-09-30   | 2019-09-30         | 2019-09-30         | 2019-09-30            | yes                       |    1 | Y                 | Y                   | NULL       | NULL       | 2019-10-04 12:08:20 | 2019-10-04 06:38:20 | NULL     |
+------------+----------------------------------+--------------+--------------+--------------------+--------------------+-----------------------+---------------------------+------+-------------------+---------------------+------------+------------+---------------------+---------------------+----------+
1 row in set (0.00 sec)

Кроме того, оба обновляются, а не только время обновления.

Я пробовал различные изменения конфигурации, но все они ведут себя одинаково.

  1. spring.jpa.properties.hibernate.jdbc.time_zone=UTC

  2. Использование пост-конструкции

    @SpringBootApplication
    public class IdotApplication {
    
    @PostConstruct
    void started() {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }
    
    public static void main(String[] args) {
        SpringApplication.run(IdotApplication.class, args);
    }
    

    }

  3. Дата вместо часового пояса

    @ CreationTimestamp private Дата creationTime;

  4. @ CreationTimestamp @Temporal (TemporalType.TIMESTAMP) private Дата creationTime;

  5. @ Column (updatable = false) @CreationTimestamp private Дата creationTime;

также serverTimezone=UTC уже определено в связи с useLegacyDatetimeCode=false

spring.datasource.url=jdbc:mysql://localhost:3306/rmcdb?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

1 Ответ

0 голосов
/ 21 октября 2019

Проблема возникла из-за возможности mysql, я использую mysql 5.7+, liquibase с raw sql для генерации схемы.

Если я создаю столбец в mysql с timestamp, по умолчанию он автоматически обновляется.

mysql> create table test ( a timestamp );
Query OK, 0 rows affected (0.02 sec)

mysql> describe test;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type      | Null | Key | Default           | Extra                       |
+-------+-----------+------+-----+-------------------+-----------------------------+
| a     | timestamp | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
1 row in set (0.00 sec)

mysql>

Когда создавалась новая запись, обе отметки времени находились в UTC часовом поясе, поскольку hibernate превосходил MySQL.

Но когда обновляется запись, on update current_timestamp из mysql срабатывает, в то время как hibernate ничего не делает, поскольку он @creationTimeStamp, следовательно, он остается в локальной временной зоне, которую поместил mysql.

Для разрешения я определил поле как

creation_time timestamp null,
updation_time timestamp null

Теперь mysql не мешает, обновление и т. Д. Все выполняется только в режиме гибернации.

Если вы находите объяснение немного запутанным и используете mysql, перейдите к статье, которая прояснится ниже. https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html

Надеюсь, это кому-нибудь поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...