Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

hibernate.jdbc.time_zone = UTC ignored

Using set up as

  • Spring framework 5.0.2.RELEASE
  • Spring Security 5.0.0.RELEASE
  • Hibernate 5.2.11.Final

I followed spring boot & Vlad's link to configure my application as below

db.properties -

jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://hostname:port/appname?useSSL=false&serverTimezone=UTC&useLegacyDatetimeCode=false
jdbc.username = xxx
jdbc.password = xxx
jdbc.minPoolSize = 5
jdbc.maxPoolSize = 20
jdbc.maxIdleTime = 30000
hibernate.dialect = org.hibernate.dialect.MySQLDialect
hibernate.show_sql = true
hibernate.format_sql = false
spring.jpa.properties.hibernate.jdbc.time_zone = UTC

HibernateConfig.java

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages="in.greenstack.ikon")
@PropertySource(value = { "classpath:/resources/db.properties" })
public class HibernateConfig {

    @Autowired
    private Environment environment;

    @Bean(name = "myDataSource")
    ....

    @Bean
    public LocalSessionFactoryBean sessionFactory() {
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setDataSource(dataSource());
        sessionFactory.setPackagesToScan(new String[] { "in.greenstack.ikon.entity" });
        sessionFactory.setHibernateProperties(hibernateProperties());
        return sessionFactory;
     }

    private Properties hibernateProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
        properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
        properties.put("spring.jpa.properties.hibernate.jdbc.time_zone", 
                environment.getRequiredProperty("spring.jpa.properties.hibernate.jdbc.time_zone"));
        return properties;        
   }

Entity -

@Entity
@Table(name = "PROJECT_MASTER")
public class Project {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private int id;

@Column(name = "NAME")
private String name;

@Column(name = "START_DATE")
private Date startDate;

@Column(name = "END_DATE")
private Date endDate;

@ManyToOne
@JoinColumn(name = "FINANCIAL_YEAR")
private FinancialYear financialYear;

Table Definition -

    CREATE TABLE `PROJECT_MASTER` (
    `ID` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(50) NOT NULL,
  `FINANCIAL_YEAR` varchar(20) DEFAULT NULL,
  `START_DATE` date DEFAULT NULL,
  `END_DATE` date DEFAULT NULL,

Logs -

    2018-06-13 16:39:03 DEBUG SQL:92 - insert into PROJECT_MASTER (ACCOUNTING_STANDARD_ID, CONVERSION_METHOD_ID, CURRENCY_ID, DESCRIPTION, END_DATE, FINANCIAL_YEAR, HIERARCHY_ID, IMPORT_FROM_PREVIOUS, NAME, OPENING_PROJECT_ID, START_DATE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into PROJECT_MASTER (ACCOUNTING_STANDARD_ID, CONVERSION_METHOD_ID, CURRENCY_ID, DESCRIPTION, END_DATE, FINANCIAL_YEAR, HIERARCHY_ID, IMPORT_FROM_PREVIOUS, NAME, OPENING_PROJECT_ID, START_DATE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2018-06-13 16:39:03 TRACE ResourceRegistryStandardImpl:55 - Registering statement [com.mchange.v2.c3p0.impl.NewProxyPreparedStatement@747dab [wrapping: com.mysql.cj.jdbc.PreparedStatement@1abace9: insert into PROJECT_MASTER (ACCOUNTING_STANDARD_ID, CONVERSION_METHOD_ID, CURRENCY_ID, DESCRIPTION, END_DATE, FINANCIAL_YEAR, HIERARCHY_ID, IMPORT_FROM_PREVIOUS, NAME, OPENING_PROJECT_ID, START_DATE) values (** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **, ** NOT SPECIFIED **)]]
2018-06-13 16:39:03 TRACE AbstractEntityPersister:2709 - Dehydrating entity: [in.greenstack.ikon.entity.Project#<null>]
2018-06-13 16:39:03 TRACE IdentifierValue:130 - ID unsaved-value: 0
2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [1] as [INTEGER] - [1]
2018-06-13 16:39:03 TRACE BasicBinder:53 - binding parameter [2] as [INTEGER] - [null]
2018-06-13 16:39:03 TRACE IdentifierValue:130 - ID unsaved-value: 0
2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [3] as [INTEGER] - [2]
2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [4] as [VARCHAR] - [TestTimeZone1 FY2017-2018 IGAAP]
**2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [5] as [DATE] - [2018-03-31]**
2018-06-13 16:39:03 TRACE IdentifierValue:130 - ID unsaved-value: 0
2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [6] as [INTEGER] - [2]
2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [7] as [INTEGER] - [30]
2018-06-13 16:39:03 TRACE BasicBinder:53 - binding parameter [8] as [BOOLEAN] - [null]
2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [9] as [VARCHAR] - [TestTimeZone1]
2018-06-13 16:39:03 TRACE BasicBinder:53 - binding parameter [10] as [INTEGER] - [null]
**2018-06-13 16:39:03 TRACE BasicBinder:65 - binding parameter [11] as [DATE] - [2017-04-01]**
2018-06-13 16:39:03 DEBUG IdentifierGeneratorHelper:78 - Natively generated identity: 63
2018-06-13 16:39:03 TRACE ResourceRegistryStandardImpl:91 - Releasing result set [com.mchange.v2.c3p0.impl.NewProxyResultSet@182014e [wrapping: com.mysql.cj.jdbc.result.ResultSetImpl@d243c6]]
2018-06-13 16:39:03 DEBUG ResourceRegistryStandardImpl:104 - HHH000387: ResultSet's statement was not registered
2018-06-13 16:39:03 TRACE ResourceRegistryStandardImpl:132 - Closing result set [com.mchange.v2.c3p0.impl.NewProxyResultSet@182014e [wrapping: com.mysql.cj.jdbc.result.ResultSetImpl@d243c6]]
2018-06-13 16:39:03 TRACE ResourceRegistryStandardImpl:68 - Releasing statement [com.mchange.v2.c3p0.impl.NewProxyPreparedStatement@747dab [wrapping: com.mysql.cj.jdbc.PreparedStatement@1abace9: **insert into PROJECT_MASTER (ACCOUNTING_STANDARD_ID, CONVERSION_METHOD_ID, CURRENCY_ID, DESCRIPTION, END_DATE, FINANCIAL_YEAR, HIERARCHY_ID, IMPORT_FROM_PREVIOUS, NAME, OPENING_PROJECT_ID, START_DATE) values (1, null, 2, 'TestTimeZone1 FY2017-2018 IGAAP', '2018-03-30', 2, 30, null, 'TestTimeZone1', null, '2017-03-31')]]**

As can be seen from above logs, that the binding parameter is the correct value (1st April 2017 & 31st March 2018) sent from client, but when saving in db it is still saving incorrect dates.

Kindly advice what I have missed.

pom.xml -

<properties>
        <spring.version>5.0.2.RELEASE</spring.version>
        <springsecurity.version>5.0.0.RELEASE</springsecurity.version>
        <mysql.connector.version>8.0.11</mysql.connector.version>
        <hibernate.version>5.2.17.Final</hibernate.version>
        <hibernate.validator.version>5.2.3.Final</hibernate.validator.version>
    </properties>
like image 776
Bhavna Jhunjhunwala Avatar asked Jun 13 '18 11:06

Bhavna Jhunjhunwala


1 Answers

I think you should put spring.jpa.properties.hibernate.jdbc.time_zone = UTC in application.yml/application.properties of main/ or test/, not in db.properties. And, I think .properties takes precedence over .yml. Correct me if I am wrong.

And, this timezone config is also affected by Timezone.getDefault().

See this post: https://aboullaite.me/spring-boot-time-zone-configuration-using-hibernate/

And, as I test, I see that if you want to save a java.util.Date, which has no timezone info in itself(only in its Calendar property, this is true), and the column definition hold no place for timezone info, this property will affect the value saved to DB, but not that when you retrieve the row from DB; the latter is affected only by Timezone.getDefault(). Meanwhile, if you set Timezone.getDefault(), the saved and retrieved value will both be the timezone you want.

So, this property may not be the most proper way to manipulate the value of Date, if you save and query for the information in the same application. Just use Timezone.setDefault(Timezone.getTimezone("XXX")).

like image 70
WesternGun Avatar answered Oct 15 '22 05:10

WesternGun