Подтвердить что ты не робот

Hibernate 5 + ZonedDateTime + postgresql inlcude часовой пояс и смещение

У меня есть загружаемое приложение spring boot 1.3 + hibernate 5 + java 8 + ZonedDateTime + postgresql, и в одной из таблиц у меня есть следующие поля.

@Column(name = "DATE_ENABLED")
@Type(type="java.time.ZonedDateTime")   
private ZonedDateTime dateEnabled;

@Column(name = "DATE_DISABLED")
@Type(type="java.time.ZonedDateTime")   
private ZonedDateTime dateDisabled;

Если я запустил приложение, то вижу, что это по умолчанию создает "временную метку без часового пояса",

testDB=# \d type
                Table "public.type"
             Column             |            Type             | Modifiers 
--------------------------------+-----------------------------+-----------
 type_id                        | bytea                       | not null
 date_disabled                  | timestamp without time zone | 
 date_enabled                   | timestamp without time zone | 

Я знаю, что если я добавлю columnDefinition = "TIMESTAMP WITH TIME ZONE" в столбец, то есть что-то вроде

@Column(name = "DATE_DISABLED", columnDefinition= "TIMESTAMP WITH TIME ZONE")

то он работает правильно, и я могу видеть, что спящий режим создал столбец с часовым поясом, но если я это правильно пойму, это будет работать только для postgres, т.е. если я завтра сменил базу данных на mysql, тогда hibernate вызовет ошибку.

Таким образом, мой вопрос заключается в том, как это сделать в общем случае, например, чтобы спящий режим мог создать столбец, который должен включать часовой пояс и смещение. Я считал, что, поскольку тип java "ZonedDateTime" намеренно создан для включения часового пояса и смещения времени в UTC, тогда hibernate по умолчанию создаст столбец с часовым поясом. Таким образом, вопрос еще раз: каков правильный способ включить спящий режим для включения часового пояса и смещения.

Вот некоторые из моих моментов:

    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.3.0.RELEASE</version>

    <hibernate.version>5.0.4.Final</hibernate.version>

    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-java8</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

и файл свойств, показывающий диалект

    @Bean
    public  Properties hibernateProperties() {
      return new Properties() {
        {
            setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
            setProperty("hibernate.chach.provider_class", "org.hibernate.cache.NoCacheProvider");
            setProperty("hibernate.show_sql", "true");              
            setProperty("hibernate.hbm2ddl.auto", "create-drop");
         }
      };
   }
4b9b3361

Ответ 1

Кажется, эта проблема является лишь препятствием, если вы используете Hibernate для создания схемы. Поэтому, если все работает хорошо после того, как вы создали столбец как timestamp with time zone на PostgreSQL, просто пойдите с этим. Во всяком случае, это плохая практика, позволяющая Hibernate генерировать вашу схему. Сделайте это вручную (или пусть DBA сделает это). Если вы хотите автоматизировать, используйте инструмент миграции базы данных, например Flyway или Liquibase после того, как надежный человек написал сценарии sql.

Кроме того, требование "изменить базу данных завтра" звучит действительно вымышленно, рабочая независимая база данных более или менее нереалистична и усложняется при написании больших приложений, которые должны выполняться.

Если вам нужна дополнительная информация о поведении временной шкалы Hibernate/JDBC, возможно, зайдите эта хорошая статья об этом.