【问题标题】:Fetch dates (by month or year) stored in TIMESTAMP using JPA使用 JPA 获取存储在 TIMESTAMP 中的日期(按月或年)
【发布时间】:2012-09-20 10:47:32
【问题描述】:

我遇到了一个问题,我希望你能帮助我。

事实证明,我的 Oracle 11g 数据库中有一张表,用于存储一台电子设备的故障。表定义如下:

CREATE TABLE failure
( failure_id NUMERIC NOT NULL
, fecha TIMESTAMP NOT NULL
, module_id NUMERIC NOT NULL
, code NUMERIC
, PRIMARY KEY(failure_id)
);

“fecha”的意思是“日期”。

我需要按年或按月获取某个特定模块的故障,但我不能。我的 ORM 将 TIMESTAMP 类型映射到 java.sql.Date 但我不知道如何比较 JPQL 句子中的月份。我曾尝试将 ORACLE 函数与本机查询一起使用,但我遇到了另一个问题:转换结果。 我正在使用 JPA 2.0 和 Eclipselink 2.3.2。

我的疑问是:

我可以在这个版本的 Eclipselink 库中使用 Oracle 函数吗?我的经验说不。

Query query = entityManager.createQuery("SELECT f FROM Failure f "
            + "WHERE EXTRACT(YEAR FROM f.fecha) = ?1 "
            + "AND f.moduleId.moduleId = ?2");
    query.setParameter(1, year);
    query.setParameter(2, idModule);

我收到此错误:Unexpected token [(]

我可以使用 Eclipselink 函数吗?我的经验说不。

Query query = entityManager.createQuery("SELECT f FROM Failure f "
            + "WHERE EXTRACT('YEAR', f.fecha) = ?1 "
            + "AND f.moduleId.moduleId = ?2");
    query.setParameter(1, year);
    query.setParameter(2, idModule);

同样的错误。

您知道仅使用一个查询来获取此数据的简单方法吗? 我知道我可以获取一个模块,然后通过循环检查故障,但我认为这不是性能最好的解决方案。

谢谢。

我的来源:

  • Eclipselink JPA 函数link
  • Eclipselink 查询增强功能link

【问题讨论】:

  • 您链接到的页面显示 EXTRACT 功能已添加到 EclipsLink 2.4,而您声明您使用的是 2.3.2。尝试更高版本。
  • @Chris 是的,你是对的。我尝试使用 EclipseLink 2.4,但无法应用新功能。我不知道出了什么问题..你用过吗?它有效吗?谢谢
  • EclipseLink 2.4 夜间测试验证提取工作:
  • 您能否详细说明什么不适合您?
  • @Chris 我已将 eclipselink 更新到 2.4.0 版,我尝试使用 EXTRACT() 运行我的测试,如下所示:Query query = entityManager.createQuery("SELECT f FROM Failure f " + "WHERE EXTRACT(YEAR,f.fecha) = ?1 " + "AND f.moduleId.moduleId = ?2 "); 我得到的错误是:表达式不是有效的条件表达式[42,42] 必须指定日期部分 [42,42] EXTRACT 表达式中缺少左括号 [43, 68] 查询包含格式错误的结尾。

标签: performance oracle jpa eclipselink jpql


【解决方案1】:

我也遇到了同样的问题。我只检查了 Oracle 的 EXTRACT 函数的正确语法,它对我有用! (注意函数语法中的 FROM 子句。

@NamedQuery(name = "Registros.findByFechacaptura", query = "SELECT s FROM Registros s WHERE EXTRACT(YEAR FROM s.fechacaptura) = EXTRACT(YEAR FROM :fechacaptura)")

【讨论】:

    【解决方案2】:

    使用

    Query query = entityManager.createQuery("SELECT f FROM Failure f "
            + "WHERE EXTRACT(YEAR from f.fecha) = ?1 "
            + "AND f.moduleId.moduleId = ?2");
    

    【讨论】:

    • 我使用的是 EclipseLInk 2.5,只有这样才能做到。
    【解决方案3】:

    我使用了 Eclipselink v 2.4 函数,我正在使用它来获取值:

    Query query = entityManager.createQuery("SELECT f FROM Failure f "
                    + "WHERE SQL('EXTRACT (YEAR FROM ?)', f.fecha) = ?1 "
                    + "AND f.moduleId.moduleId = ?2 ");
    

    从存储在数据库中的日期中提取年份可以避免两个日期之间的比较。

    【讨论】:

      【解决方案4】:

      EclipseLink 2.4 中 EXTRACT 的语法是,

      EXTRACT(YEAR, f.fecha)
      

      http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Functions

      【讨论】:

      • 我可以在SELECTWHERE 一侧这样做吗?
      • 不适合我。 Query query = entityManager.createQuery("SELECT f FROM Failure f " + "WHERE EXTRACT (YEAR, f.fecha) = ?1 " + "AND f.moduleId.moduleId = ?2 "); 我看到一些错误 EXTRACT 表达式中缺少左括号,必须指定日期部分,查询包含格式错误的结尾。
      • 我现在收到此错误:unexpected token [(]. Internal Exception: NoViableAltException(83@[()* loopback of 383:9: (d=DOT right=attribute)*] 可能与 Eclipselink 库有关吗?
      • 试试EXTRACT(YEAR from f.fecha),用户指南中提到的函数用法有误,@see eclipse.org/eclipselink/api/2.4/org/eclipse/persistence/jpa/…
      【解决方案5】:

      本机查询是用数据库的 SQL 方言编写的,因此可以使用数据库特定的功能,请参阅 EntityManager 的 createNativeQuery 方法。

      但是还有另一种解决方案,根据上下限值测试时间戳:

      WHERE f.fecha >= '2012-9-1' AND f.fecha < '2012-10-1'
      

      【讨论】:

      • 您好,Eelke,感谢您的回复。是的,我知道 CreateNativeQuery 但它通常返回一个对象,然后我应该将它转换为我的特定对象。我不喜欢这种方式。最后我决定使用两个日期来获取整月或整年。感谢您的回复和关注。
      • 我认为在这种情况下使用 Eclipselink 函数比比较两个日期要好。这就是为什么我更改了正确答案,即使您的解决方案运行良好。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      相关资源
      最近更新 更多