代码之家  ›  专栏  ›  技术社区  ›  zappee

MyBatis+MyBatis CDI+PostgreSQL的时区问题

  •  1
  • zappee  · 技术社区  · 8 年前

    我在MyBatis有一个奇怪的时区问题。

    环境:

    • mybatis v3.4.5
    • mybatis cdi v1.0.1
    • Payara app Server v4.1.2.173
    • PostgreSQL数据库

    一开始 我正在将一条记录插入一个有日期时间字段的表中。 在Java方面,它是一个 java.time.ZonedDateTime . 在我使用的数据库中 TIMESTAMP WITH TIME ZONE

    这是相关代码:

    request.setRequestDate = ZonedDateTime.now();
    LOGGER.info("xxx-xxx-xxx: " + httpRequest.getRequestDate());
    myMapper.save(request);
    

    在日志文件中,我可以看到:

    [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
    

    在数据库中,结果如下:

    select request_date from table_a
    result: 2017-10-18 16:43:45.493
    

    GMT+2 将时区输入数据库,而不是 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
    

    如您所见,该值插入了错误的时区:

    select uploaded from table_b
    result: 2017-10-18 18:43:46.188
    

    sessionTimeZone=UTC
    

    但我仍然在UTC中插入第一个日期时间,在UTC+2时区中插入第二个日期时间。

    我试图注销java的详细信息。sql。连接来看看这里到底发生了什么,所以我在代码中注入了sqlsqession(@Inject-SqlSession-SqlSession),但当然我得到了一个 org.apache.ibatis.session.SqlSessionException: Error: Cannot get connection. No managed session is started..

    知道要检查什么吗?

    -----更新1-----

    因此,我根据建议将所有内容更改为UTC:

    • 应用服务器:-Duser。时区=UTC

    当我在PostgreSQL控制台中执行查询时,结果如下:

    demo=# select EXTRACT(TIMEZONE FROM uploaded), uploaded from image_metadata;
     date_part |          uploaded
    -----------+----------------------------
             0 | 2017-10-25 00:24:11.873+00
    (1 row)
    

    SqurielSQL中的相同查询结果:

    date_part   uploaded
    0           2017-10-25 02:24:11.873
    

    我的SQL客户端似乎在后台进行了一些复杂的时区对话,但我不确定。我需要检查一下。

    我不确定是什么问题,但在我将数据库和JVM时区设置更改为UTC后,我的问题得到了解决。

    我使用以下SQL查询从数据库中获取存储的日期时间值:

    SELECT current_timestamp AT TIME ZONE 'UTC'
    
    1 回复  |  直到 8 年前
        1
  •  0
  •   Community Mohan Dere    6 年前

    我会将一切设置为UTC,使一切变得更简单。

    LOGGER.info(TimeZone.getDefault().getID())
    

    -Duser.timezone=UTC 应用程序启动。

    代码段变量中存在混乱 request / httpRequest ,也许只是一个拼写错误?

    要求 .setRequestDate=ZoneDateTime。现在();

    httpRequest .getRequestDate());