我用Spring 4.2.5 + Hibernate 5.1.0开发了一个简单的应用程序,数据库系统是MS SQL Server 2014。
从几天我挣扎正确存储时间+时区在数据库。
我需要满足的要求是:
- 保存所有日期在UTC时区。
- 在数据库列值中存储时区。
为了实现它,我创建了一个名为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()));
}
}
你知道我怎么解决这个问题吗?
- 我应该在模型中使用其他日期类型吗?与时间戳不同? 在MS SQL server数据库中DATE_列应该是什么样的类型?
我将感激任何帮助。谢谢你。
问题出在监听器上。在监听器中替换以下代码并进行验证。根据需要更改日期格式。
@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.jpa.properties.hibernate.jdbc.time_zone=UTC
这对我来说很奇怪,在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"));
}
}