【问题标题】:Spring + Hibernate + MS SQL server - UTC time zoneSpring + Hibernate + MS SQL 服务器 - UTC 时区
【发布时间】:2016-12-13 22:24:39
【问题描述】:

我使用 Spring 4.2.5 + Hibernate 5.1.0 开发了简单的应用程序 - 数据库系统是 MS SQL Server 2014。

从几天开始,我一直在努力在数据库中正确存储时间 + 时区。

我需要满足的要求是:

  1. 以 UTC 时区保存所有日期。
  2. 将时区存储在数据库列值中。

为了实现它,我创建了名为 MyComment 的模型:

@Entity
@Table(name = "MY_COMMENT")
@EntityListeners(value = { MyCommentListener.class })
@Audited
public class MyComment implements Serializable {

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

    @Column(name = "DATE_", nullable = false)
    private Timestamp date;

    ...
}

为了强制在 UTC 时区保存日期,我使用了 Jadira 框架:

    hibProperties.put("jadira.usertype.autoRegisterUserTypes", true);
    hibProperties.put("jadira.usertype.javaZone", "UTC");
    hibProperties.put("jadira.usertype.databaseZone", "UTC");

但是,在 MyComment 对象的每次创建/更新操作期间,MyCommentListener 都会从我的本地时区(不是 UTC 日期!)获取日期:

public class MyCommentListener {

    @PreUpdate
    @PrePersist
    public void setLastUpdate(MyComment myComment) {
        myComment.setDate(new Timestamp(System.currentTimeMillis()));
    }

}

你知道我该如何解决这个问题吗?

  1. 我应该在我的模型中使用其他日期类型吗?不同于时间戳?
  2. MS SQL server 数据库中的 DATE_ 列应该是什么类型?

我将不胜感激。谢谢。

【问题讨论】:

  • 也许您应该添加一个“jadira”标签。您还应该指定是否要将时区 nameoffset 存储在数据库列中。
  • 您能再描述一下吗?我不明白你的意思。
  • jadira 标签,因为您使用的是它们的类型。您的要求似乎是技术性的(存储 UTC),但随后是“将时区存储在数据库列值中”。错过指定时区偏移量或标识符。 Identifier 有更多信息,见w3.org/TR/timezone/#tzidsw3.org/TR/timezone/#datetime 这取决于你需要做什么。存储时区的目的是什么?

标签: sql-server spring hibernate datetime timezone


【解决方案1】:

AFAIK,问题出在听众身上。在侦听器中替换以下代码并验证。根据需要更改日期格式。

    @PreUpdate
    @PrePersist
    public void setLastUpdate(MyComment myComment) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
        dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        myComment.setDate(dateFormat.getCalendar().getTime());
    }

【讨论】:

  • 是的,你是对的。该代码将起作用,但我正在寻找一个通用解决方案,该解决方案将在我的 Spring 应用程序中默认使用 UTC 时区。假设我有 10 个听众正在为我的模型注入时间,那么我需要重复上述代码 10 次。我预计由于我使用的是 Jadira,它将使用 UTC 时区作为默认时区。
  • 如果你想把你的整个应用程序设置为 UTC 然后在启动时使用它 TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
【解决方案2】:

Spring 中没有设置默认 TimeZone 的属性对我来说很奇怪——至少我不知道。

经过一番谷歌搜索,我发现Spring设置时区的最佳位置是WebApplicationInitializer,所以我准备了以下代码:

public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(final ServletContext servletContext) throws ServletException {
        setupTimeZone();
    }

    private void setupTimeZone() {
        TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    }
}

【讨论】:

    【解决方案3】:

    您可以在应用程序属性文件中设置时区属性,如下所示。

    spring.jpa.properties.hibernate.jdbc.time_zone=UTC
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-13
      • 1970-01-01
      • 2021-05-24
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多