【问题标题】:JPA, custom query and datesJPA、自定义查询和日期
【发布时间】:2013-03-18 03:23:14
【问题描述】:

我遇到了一个奇怪的问题。我已经在堆栈溢出中进行了搜索,对于 JPA 和自定义查询,我应该指定参数。所以我有一个查询字符串,因为我有超过 14 个字段,但我遇到了日期问题。我总是收到 IllegalStateException

INFO: query STRING = SELECT t FROM Tickets t  WHERE t.startdate > :startDate AND t.enddate < :endDate ORDER BY t.status DESC
WARNING: #{ticketController.search}: java.lang.IllegalStateException: Query argument startDate not found in the list of parameters provided during query execution.

至于我的查询:

Query q = em.createQuery(query).setParameter("startDate", startDate, TemporalType.TIMESTAMP).setParameter("endDate", endDate, TemporalType.DATE);

虽然我发现该参数未找到,但我在 setParameter 中有它,并且还在查询中设置了它,如 INFO 行中所示。

有什么想法吗?

提前致谢

编辑:

INFO: query STRING = SELECT t FROM Tickets t  WHERE t.startdate > ?1 AND t.enddate < ?2 ORDER BY t.status DESC
WARNING: #{ticketController.search}: java.lang.IllegalStateException: Query argument 1 not found in the list of parameters provided during query execution.

q = em.createQuery(query).setParameter(1, startDate, TemporalType.TIMESTAMP).setParameter(2, endDate, TemporalType.TIMESTAMP);

另外,按照建议,我检查了我使用的日期是 java.util.Date。在实体类中我有时间戳。但是我仍然无法正常工作,并且不确定我在哪里失败。

为了确保所有的事情都是他们应该做的,我强制查询是字符串,我得到了正确的异常:

INFO: query STRING = SELECT t FROM Tickets t  WHERE t.startdate > :startDate AND t.enddate < :endDate ORDER BY t.status DESC
WARNING: #{ticketController.search}: java.lang.IllegalArgumentException: You have attempted to set a value of type class java.lang.String for parameter startDate with expected type of class java.util.Date 

但话又说回来,我更改为日期,但它失败了:S 我已经检查了这个 IllegalStateException 的原因:

从调试和javadoc 我得到以下信息: 获取结果列表

IllegalStateException - 如果为 Java Persistence 查询语言 UPDATE 或 DELETE 语句调用。

我不更新也不删除:/

编辑 2:添加实体相关部分:

@Basic(optional = false)
@NotNull
@Column(name = "startdate")
@Temporal(TemporalType.TIMESTAMP)
private Date startdate;
@Column(name = "enddate")
@Temporal(TemporalType.TIMESTAMP)
private Date enddate;

对于数据库创建脚本,列的创建方式如下:

  startdate timestamp with time zone NOT NULL,
  endate timestamp with time zone,

如果我执行正常的 SQL 查询,例如: "select * from tbl_tickets where startdate > '2012-02-01 00:00:00' and enddate

我得到了想要的结果。我想我可以使用本机查询,但这会解决问题而不是解决这个问题,对吧?

编辑 3: 虽然我已经正确设置了所有内容,但 bean 的 init 再次调用了没有 args 的查询(抱歉,谢谢大家的帮助。它帮助我检查了什么是错了)

【问题讨论】:

  • endate 在 SQL 中是一个错字,对吧?应该是enddate

标签: java datetime jpa


【解决方案1】:

两者的javadoc

setParameter(String name, java.util.Date value, TemporalType temporalType)`
setParameter(String name, java.util.Calendar value, TemporalType temporalType)`

状态:

抛出:IllegalArgumentException - 如果参数名称与查询的参数不对应,或者 value 参数的类型不正确

由于您没有提供完整代码,请验证:

  • Java 值 startDate 的类型为 java.util.Datejava.util.Calendar

  • SQL 列 startDate 具有有效的 SQL 日期类型 TIMESTAMP

【讨论】:

  • 谢谢我更新了问题,验证后没有问题。我还应该提到,当在数据库中创建记录时,应用程序会使用日期类型的对象自动设置开始日期。并且正确保存,没有错误。
  • 你真的让每个人都在猜测。请展示:a) 用于创建表的 SQL,以及 b) Java 实体的相关部分。
  • 您的代码中仍然缺少一块 - 设置查询的变量和代码。这些变量是如何声明的?它们必须是 java Date 或 Calendar,对吧?
  • 接受主要是因为上述评论实际上帮助我找到了我的问题和解决方案。谢谢
【解决方案2】:

我认为 :(冒号)和 startDate 之间应该有一个空格。可能是将 :startDate 视为一个词。试试这个

【讨论】:

    【解决方案3】:

    试试

    String query = "SELECT t FROM Tickets t  WHERE t.startdate > ?1 AND t.enddate < ?2 ORDER BY t.status DESC";
    

    Query q = em.createQuery(query).setParameter(1, startDate, TemporalType.TIMESTAMP).setParameter(2, endDate, TemporalType.DATE);

    【讨论】:

      【解决方案4】:
      Query q = em.createQuery(query).setParameter("startDate", startDate, TemporalType.TIMESTAMP).setParameter("endDate", endDate, TemporalType.DATE);
      

      如果您仔细查看您正在使用的setParameter,它会说这个setParameter 需要Positional Parameter,而查看您的查询,您似乎使用了Named Parameter

      因此,IllegalStateException。将您的查询更改为提供Positional Parameters,或更改setParameter 以提供Named Parameters 作为输入。

      这就是您在查询中提供Positional Parameter 的方式。

      String query = "SELECT t FROM Tickets t  WHERE t.startdate > ?1 AND t.enddate < ?2 ORDER BY t.status DESC";
      ....
      Query q = em.createQuery(query).setParameter(1, startDate, TemporalType.TIMESTAMP).setParameter(2, endDate, TemporalType.DATE);
      

      【讨论】:

      • 感谢您的信息。我已经尝试过你提到的但仍然是同样的问题。我只有在调用 q.getResultList 时才得到这个。在那之前,尽管在调试模式下我看到 jpql 查询被标记为“startdate > ?”,但变量已被正确填充。非常感谢您的解释,我会错过很长时间的命名 vs 位置。
      • 它现在说IllegalArgumentException,这意味着局部变量startDate不是Date类型。这似乎是唯一可能的情况。
      • 表示该行实际上正在执行。当强制类型为字符串时,我这样做是为了测试。我仍然得到状态异常。
      • Hm.. 还有一个 setParameter 方法用于设置命名参数,我认为问题描述中的代码使用它:docs.oracle.com/javaee/6/api/javax/persistence/…
      猜你喜欢
      • 1970-01-01
      • 2019-03-10
      • 2019-06-10
      • 1970-01-01
      • 2015-10-27
      • 1970-01-01
      • 1970-01-01
      • 2015-03-25
      • 1970-01-01
      相关资源
      最近更新 更多