【问题标题】:Adding X hours - @Query - Spring Data JPA添加 X 小时 - @Query - Spring Data JPA
【发布时间】:2019-01-27 01:07:12
【问题描述】:

我尝试在 Spring Data JPA Repository 中创建一种不同的方法,该方法应该将给定的小时数添加到时间戳。

public interface ActivationCodeRepository extends CrudRepository<ActivationCode, Long> {

  @Query(value = "select a from ActivationCode a where a.creationTime + INTERVAL '1 hour' * :hoursAgo  <=  CURRENT_TIMESTAMP and a.type = :type and a.account = account")
  List<ActivationCode> getAllAddedAtLeastXHoursAgo(@Param("account") Account account, @Param("type") int type, @Param("hoursAgo") int hoursAgo);


}

因为它不工作:

  • INTERVAL '1 小时' * :hoursAgo

完全正确:

'1 小时'

IDE 下划线并给出此错误:

、、GROUP、HAVING 或 ORDER 预期。

我已经尝试做一些研究,并找到我应该如何将给定的时间添加到 creationTime 但在任何地方都找不到。

【问题讨论】:

  • 我不认为像 JPA 这样的混淆层支持 INTERVAL 文字。您将需要一个本机查询。

标签: java postgresql hibernate spring-data-jpa


【解决方案1】:

如果这么长时间以来有人感兴趣,我会以最卑鄙的方式做到这一点。但它奏效了。

@Query注解如下;

@Query("SELECT q FROM QueryStatusDao q WHERE q.jobStatus='Submit' AND q.submitTime < now() - :interval")
List<QueryStatusDao> getRunnableParkedQueries(@Param("interval")String interval);

我这样称呼这个方法;

queryStatusRepository.getRunnableParkedQueries("INTERVAL '1 hour'");

如果我发现任何其他非卑鄙的方法来做到这一点,我会更新。

【讨论】:

    【解决方案2】:

    就像a_horse_with_no_name 说我必须使用本机查询来做类似的事情,所以我将方法更改为:

      @Query(value = "select * from activation_codes a where a.type = :type and a.id_account = :id_account and a.creation_time <= NOW() - :hoursAgo * INTERVAL '1 hour'", nativeQuery = true)
      List<ActivationCode> getAllAddedAtLeastXHoursAgo(@Param("id_account") int id_account, @Param("type") int type, @Param("hoursAgo") int hoursAgo);
    

    而且它工作正常。 感谢大家的帮助。

    【讨论】:

      【解决方案3】:

      我不相信 PostgreSQL 允许传递 INTERVAL 语句需要带有 interval '1 day' 样式输入的硬编码字符串;但是,您可以通过将字符串转换为间隔来实现。

      尝试将代码中的 SQL 查询更改为:

      select a from ActivationCode a where a.creationTime + (:hoursAgo||' hour')::interval <=  CURRENT_TIMESTAMP and a.type = :type and a.account = account
      

      或者,我刚刚找到this previous StackOverflow answer,这值得一试,但可能会遇到同样的问题(假设它与 Spring Data JPA 的查询解析器有关):

      select a from ActivationCode a where a.creationTime + :hoursAgo * INTERVAL '1 hour' <=  CURRENT_TIMESTAMP and a.type = :type and a.account = account
      

      【讨论】:

      • INTERVAL '1 hour' * 5 在 Postgres 中绝对有效,但对 JPA 无效
      • 同意,这就是为什么我怀疑问题出在 JPA 的查询解析器上;不过,绝对值得尝试我的答案中的第一个建议(将间隔构建为字符串并使用::interval 进行强制转换),这可能会解决 JPA 查询解析器的限制。我强烈怀疑我的答案中的第二个示例(只是交换乘法参数)将与原始查询存在相同的问题。
      • 感谢您的建议,但没有 nativeQuery 我无法做到。
      猜你喜欢
      • 1970-01-01
      • 2018-08-31
      • 1970-01-01
      • 2015-07-14
      • 2021-08-27
      • 2014-08-31
      • 2017-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多