首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MyBatis + MyBatis CDI + PostgreSQL时区问题

MyBatis + MyBatis CDI + PostgreSQL时区问题
EN

Stack Overflow用户
提问于 2017-10-18 17:39:30
回答 1查看 2.4K关注 0票数 1

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

环境:

  • 紫花莲v3.4.5
  • 马钱提-CDI v1.0.1
  • Payara应用服务器v4.1.2.173
  • PostgreSQL数据库
  • JNDI数据源、托管事务设置

首先,,我在有日期-时间字段的表中插入一个记录。在Java方面,它是一个java.time.ZonedDateTime。在数据库中,我对此字段使用TIMESTAMP WITH TIME ZONE

以下是相关代码:

代码语言:javascript
复制
request.setRequestDate = ZonedDateTime.now();
LOGGER.info("xxx-xxx-xxx: " + httpRequest.getRequestDate());
myMapper.save(request);

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

代码语言:javascript
复制
[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

在数据库中,这是结果:

代码语言:javascript
复制
select request_date from table_a
result: 2017-10-18 16:43:45.493

没关系,因为我在数据库中使用GMT时区。

然后,我在同一个数据源上使用不同的映射类执行另一个sql ( POJO是不同的),但是和类型是相同的。问题是日期-时间值是用GMT+2时区插入到数据库中的,而不是GMT

代码语言:javascript
复制
[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

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

代码语言:javascript
复制
select uploaded from table_b
result: 2017-10-18 18:43:46.188

我最初的猜测是,它来自错误的数据库池设置,因此我在池配置中添加了以下属性:

代码语言:javascript
复制
sessionTimeZone=UTC

但我仍在UTC插入第一次约会时间,在UTC+2时区插入第二次约会时间。

我试图注销java.sql.Connection的详细信息,以了解到底是怎么回事,所以我将SqlSqssion注入代码(@Inject SqlSession sqlSession),但我当然得到了org.apache.ibatis.session.SqlSessionException: Error: Cannot get connection. No managed session is started..异常,因为我使用托管事务处理。

知道要查什么吗?

-更新1

因此,我按照以下建议将所有内容更改为UTC:

  • postgresql.conf:时区= 'UTC‘
  • app服务器:-Duser.timezone=UTC

看起来没问题但是..。

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

代码语言:javascript
复制
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中的相同查询结果:

代码语言:javascript
复制
date_part   uploaded
0           2017-10-25 02:24:11.873

我的SQL客户端似乎在后台做了一些棘手的时区对话,但我不确定。我要检查一下。

-更新2

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

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

代码语言:javascript
复制
SELECT current_timestamp AT TIME ZONE 'UTC'
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-20 09:57:54

我会在UTC设置每件事,使一切变得更简单。

代码语言:javascript
复制
LOGGER.info(TimeZone.getDefault().getID())

如果它显示的不是UTC,那么将VM参数-Duser.timezone=UTC添加到应用程序启动。

代码片段变量request / httpRequest中存在混淆,可能只是一个错误?

request.setRequestDate = ZonedDateTime.now(); (“xxx-xxx-xxx:”+ httpRequest.getRequestDate());)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46816100

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档