JPQL 和带时区的时间戳

Posted

技术标签:

【中文标题】JPQL 和带时区的时间戳【英文标题】:JPQL and timestamp with timezone 【发布时间】:2010-11-10 00:00:31 【问题描述】:

我的一个 JPA 实体中有以下字段定义:

@Column(nullable = false, name = "start_time",
columnDefinition= "TIMESTAMP WITH TIME ZONE")
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date startTime = new Date();

@Column(nullable = true, name = "end_time",
columnDefinition= "TIMESTAMP WITH TIME ZONE")
@Temporal(javax.persistence.TemporalType.TIMESTAMP)
private Date endTime = null;

数据库是 PostgreSQL,不能使用不带时区的时间戳。关于时区的插入和更新进展顺利。当我尝试对某些测试数据运行 SELECT JPQL 查询并且过滤器参数是 Date 对象时,就会出现一个问题(至少我是这么认为的)。 OpenJPA 生成的查询不包括参数中的时区。 谁能给我一些关于 JPA 和时区列的时间戳的指导?

【问题讨论】:

【参考方案1】:

当它们存储在数据库中时,我会避免在 JPA 实体中使用日期和日历。 标准 JDBC 时间值没有时间戳的概念。

我改用下面的样式

private Long effectiveDate;
public Date getEffectiveDate() 
  if (effectiveDate == null)  return null; 
  return new Date(effectiveDate);

public void setEffectiveDate(Date d) 
  if (d == null)  effectiveDate = null; 
  effectiveDate = d.getTime();

实际上,存储在数据库中的数据是一个简单的 long 值。但是,在应用层上,您仍然使用具有时区概念的 Date 对象。

现在,有时您仍希望在数据库级别存储日期以进行查询。在这种情况下,您可以执行以下操作

private Long effectiveDate;
private Date effectiveDateDate;
public Date getEffectiveDate() 
  if (effectiveDate == null)  return null; 
  return new Date(effectiveDate);

public void setEffectiveDate(Date d) 
  effectiveDateDate = d;
  if (d == null)  effectiveDate = null; 
  effectiveDate = d.getTime();

【讨论】:

【参考方案2】:

你可以看看 java.util.Calendar。

【讨论】:

以上是关于JPQL 和带时区的时间戳的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 错误地从没有时区的时间戳转换为有时区的时间戳

在没有时区的时间戳的字段上加入没有时区的 generate_series 时间戳时遇到问题

时区、时间戳、 时区、格林威治(GMT)、协调世界时(UTC)的关系

Debezium 时间戳问题,无法转换为本地时区

数据类型“带时区的时间戳”中的时区存储

不同时区转换时间戳