JPA,自定义查询和日期

时间:2013-03-18 03:23:15

标签: java datetime jpa

我面临一个奇怪的问题。我搜索包括堆栈溢出和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。在实体类中我有Timestamp。但我仍然无法做到这一点,也不确定我失败的地方。

为了确保所有内容都符合要求,我强制查询为字符串,我得到了正确的异常:

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我得到以下内容: getResultList

IllegalStateException - 如果调用Java持久性查询语言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;

数据库创建脚本的AS正在创建列,如下所示:

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

如果我执行正常的SQL查询,例如: “select * from tbl_tickets where startdate&gt;'2012-02-01 00:00:00'and enddate&lt;'2013-03-18 23:59:50'”

我得到了理想的结果。我想我可以使用原生查询,但这会解决问题,而不是解决这个问题,对吗?

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

4 个答案:

答案 0 :(得分:5)

两者的javadoc

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

规定:

  

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

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

尝试

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);

答案 3 :(得分:0)

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

如果您仔细查看自己使用的setParameter,则表示此setParameter需要Positional Parameter,而在查看您的查询时,您似乎已使用{{ 1}}。

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

这是您在查询中提供Named Parameters的方式。

Positional Parameter