Reputation: 22746
I have a strange time-zone issue in MyBatis.
Environment:
At first I am inserting a record into a table where there is a date-time field.
On Java side it is a java.time.ZonedDateTime
. In the database I use TIMESTAMP WITH TIME ZONE
for this field.
This is the relevant piece of code:
request.setRequestDate = ZonedDateTime.now();
LOGGER.info("xxx-xxx-xxx: " + httpRequest.getRequestDate());
myMapper.save(request);
In the logfile I can see this:
[INFO ] 2017-10-18 18:43:45,501 com..................... - xxx-xxx-xxx: 2017-10-18T18:43:45.493+02:00[Europe/Prague]
[DEBUG] 2017-10-18 18:43:45,608 com...xxxDao.saveRequest - ==> Preparing: INSERT INTO table_a (id, ..., request_date) VALUES (?, ?, ...)
[DEBUG] 2017-10-18 18:43:45,770 com...xxxDao.saveRequest - ==> Parameters: 281(Long), ..., 2017-10-18 16:43:45.493(Timestamp)
[DEBUG] 2017-10-18 18:43:45,783 com...xxxDao.saveRequest - <== Updates: 1
In the database this is the result:
select request_date from table_a
result: 2017-10-18 16:43:45.493
That is okay because I use GMT time zone in the database.
Then I am executing another sql insert on the same datasource with different mapper class (the POJO is different ass well), but the Java and SQL types are same. The issue is that the date-time value is inserted with GMT+2
timezone into the database instead of GMT
:
[INFO ] 2017-10-18 18:43:46,188 com..................... - yyy-yyy-yyy: 2017-10-18T18:43:46.188+02:00[Europe/Prague]
[DEBUG] 2017-10-18 18:43:46,190 com...yyyDao.saveMetadata - ==> Preparing: INSERT INTO table_b (id,..., uploaded) VALUES (?, ?, ...)
[DEBUG] 2017-10-18 18:43:46,202 com...yyyDao.saveMetadata - ==> Parameters: 561(Long), ..., 2017-10-18 18:43:46.188(Timestamp)
[DEBUG] 2017-10-18 18:43:46,212 com...yyyDao.saveMetadata - <== Updates: 1
As you can see the value is inserted with wrong time-zone:
select uploaded from table_b
result: 2017-10-18 18:43:46.188
My first guess was it comes from the wrong database pool settings so I have added the following property to my pool configuration:
sessionTimeZone=UTC
But I am still inserting the 1st date-time in UTC and the 2nd in UTC+2 time-zone.
I have tried to log out the details of the java.sql.Connection to see what a hell is going here so I injected SqlSqssion into my code (@Inject SqlSession sqlSession) but of course I got a org.apache.ibatis.session.SqlSessionException: Error: Cannot get connection. No managed session is started..
exception because I use MANAGED transaction handling.
Any idea what to check?
----- UPDATE 1 -----
So I changed everything to UTC as per the suggestion:
It seems okay, BUT...
When I execute my query in PostgreSQL console this is the result:
demo=# select EXTRACT(TIMEZONE FROM uploaded), uploaded from image_metadata;
date_part | uploaded
-----------+----------------------------
0 | 2017-10-25 00:24:11.873+00
(1 row)
Same query result in SqurielSQL:
date_part uploaded
0 2017-10-25 02:24:11.873
It seems that my SQL client does some tricky timezone conversation at the background but I am not sure. I need to check it.
----- UPDATE 2 -----
I am not sure what was the problem but my issue was solved after I have changed the database and JVM timezone setting to UTC.
I use the following SQL query to get back the stored date-time value from database:
SELECT current_timestamp AT TIME ZONE 'UTC'
Upvotes: 1
Views: 3090
Reputation: 2044
I would set everything at UTC to make everything simpler.
LOGGER.info(TimeZone.getDefault().getID())
If it displays anything else than UTC, then add VM argument -Duser.timezone=UTC
to the application startup.
There is a confusion in the snippet variables request
/ httpRequest
, maybe just a typo ?
request.setRequestDate = ZonedDateTime.now();
LOGGER.info("xxx-xxx-xxx: " + httpRequest.getRequestDate());
Upvotes: 0