【问题标题】:Filter for TIME part of TIMESTAMP doesn't work (JPA2, HIBERNATE)过滤 TIMESTAMP 的 TIME 部分不起作用(JPA2、HIBERNATE)
【发布时间】:2016-05-26 14:40:01
【问题描述】:

我想按时间戳的时间部分进行过滤。 我将 JPA2 与 hibernate 和 oracle 数据库一起使用。我必须编写一个 JPA 查询,它返回实体,其中“std”属性的 TIME 部分高于参数的 TIME 部分。 我无法更改数据库端,也无法使用本机查询。

例如,我想搜索标准时间大于 12:01 的所有实体。所以我把这个日期参数放在我的 JPA 查询中:2013-11-11T12:01:01,但没有任何反应,结果列表包含 std 参数 (11:00) 2013-12-13T11:00:00 的元素。

我的查询如下所示:

Query q = em.createQuery( "SELECT t  FROM Foo t WHERE t.std >= :p_1 ");
q.setParameter("p_1", myDate, TemporalType.TIME);

我的日期在哪里:2013-12-11T12:01:01 (如果我使用 toString:Wed Dec 11 12:01:01 UTC 2013)

在 Entity 类中,std 属性如下所示:

private java.util.Date std;

@javax.persistence.Column(name = "STD", nullable = false, insertable = true, updatable = true)
@javax.persistence.Temporal(javax.persistence.TemporalType.TIMESTAMP)
public java.util.Date getStd()
{
    return std;
}

public void setStd(java.util.Date value)
{
    this.std = value;
}

我也试过把entityClass中属性的注解改成这样:

@javax.persistence.Temporal(javax.persistence.TemporalType.TIME)
public java.util.Date getStd()
{
    return std;
}

但它没有帮助。

在sql中,std属性是TIMESTAMP:

"STD" TIMESTAMP (6) NOT NULL ENABLE,

我必须将 JPA 查询与休眠一起使用,本机查询不是一个选项。 有人可以解释为什么它不起作用,我该如何正确地做到这一点?

谢谢!

编辑:

例如,如果数据库中的标准值如下:

2013-12-08T10:00:00 
2013-12-08T14:00:00 
2013-12-11T10:00:00 
2013-12-11T14:00:00 
2013-12-14T10:00:00 
2013-12-14T14:00:00 

我把 "2013-12-11T12:00:00" 放在查询中,我想取回 "std" 更高的所有实体TIME,与日期无关。在本例中,这些:

2013-12-08T14:00:00
2013-12-11T14:00:00 
2013-12-14T14:00:00 

如果我检查休眠调试日志,我可以看到 std 映射到 org.hibernate.TimeType。

[org.hibernate.hql.internal.ast.tree.DotNode] (http-/127.0.0.1:8080-1) getDataType() : std -> org.hibernate.type.TimeType@f600d7a

[org.hibernate.hql.internal.ast.tree.FromReferenceNode] (http-/127.0.0.1:8080-1) 已解决:t.std -> foo0_.STD

[org.hibernate.hql.internal.ast.tree.FromReferenceNode] (http-/127.0.0.1:8080-1) 已解决:t -> foo0_.ID

【问题讨论】:

  • ... 该表中是否有超过一天的数据?你想在第二天(或任何其他时间)发生什么?
  • 编辑了我的问题,并在里面放了一个例子。无论从日期部分开始,我都想取回所有实体(即使日期部分在将来),其中 std 的时间部分高于示例日期的时间部分。 (我必须将完整日期存储在数据库中以供其他查询,但这里我只想按日期的时间部分进行过滤)
  • 我解决了,更新了答案
  • 别忘了接受你自己的答案! (如果可以的话)

标签: java sql hibernate jpa


【解决方案1】:

您显然可以在 Hibernate/HQL 中使用(至少一些)SQL 函数。这包括CAST,并要求数据库做出适当的响应(即TIME 类型存在并且可以从TIMESTAMP 转换)。 如果它有效,它可能会像这样工作:

Query q = em.createQuery( "SELECT t  FROM Foo t WHERE CAST(t.std as TIME) >= :p_1 ");

(请注意,我没有支持 db/Hibernate 实例来测试它。也可能取决于 Hibernate 的版本。)

请注意,这将忽略任何索引!这更多是因为您只查询部分数据,而不是 Hibernate 的一些缺陷

【讨论】:

  • 谢谢。我试过了,但它不适用于 hibernate 4.2 和 oracle11g。
【解决方案2】:

解决办法是:

Query q = em.createQuery( 
    "SELECT t FROM Foo t WHERE ( EXTRACT(HOUR FROM t.std) * 60 + EXTRACT(MINUTE FROM t.std) ) >= :p_1" 
    );

Calendar cal = Calendar.getInstance();
cal.setTime(myDate);

int minutes = cal.get(Calendar.HOUR_OF_DAY) * 60 + cal.get(Calendar.MINUTE);
q.setParameter("p_1", minutes);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-10
    • 2018-05-31
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 2015-12-09
    • 2017-06-03
    相关资源
    最近更新 更多