Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate 5 + ZonedDateTime + postgresql include time zone and the offset

I have a running app spring boot 1.3 + hibernate 5 + java 8 + ZonedDateTime + postgresql and in one of the tables I have the following fields.

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

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

If I run the app then I see that this by default produces "timestamp without time zone"

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 | 

I know that if I add the columnDefinition= "TIMESTAMP WITH TIME ZONE" to the column i.e. something like

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

then it works correctly and I am able to see that hibernate created a column with time zone, but if I understand this correctly this will be only working for postgres i.e. if I change the database tomorrow to mysql then hibernate will throw an error.

Thus my question is how to do that in general i.e. to tell hibernate to create a column that should include the time zone and the offset. I was of the opinion that since the java type "ZonedDateTime" is deliberately created to include the time zone and the time offset in UTC then hibernate will by default create a column that include the time zone. Thus the question again: what is the proper way to tell hibernate to include the time zone and the offset.

Here are parts of my pom:

    <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>

and my properties file showing the dialect

    @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");
         }
      };
   }
like image 896
Tito Avatar asked Nov 30 '15 22:11

Tito


1 Answers

It seems this problem is only an obstacle if you use Hibernate for schema creation. So if everything works well after you created the column as timestamp with time zone on PostgreSQL, just go with that. Anyway it's a bad practice to let Hibernate generate your schema. Do it manually (or let a DBA do that). If you want to automate, use a database migration tool like Flyway or Liquibase after a reliable person wrote the sql scripts.

Beside this, the requirement "change the database tomorrow" sounds really fictional, working database independent is more or less unrealistic and gets harder on writing bigger applications which have to perform.

If you need more information about Hibernate / JDBC timestamp behavior, maybe check out this nice article about that.

like image 153
Kevin Peters Avatar answered Oct 24 '22 05:10

Kevin Peters