0

我正在开发一个 Spring Web 应用程序,其持久层包含在 Spring Roo 生成的 JPA 实体中,Hibernate 作为持久性提供者,MySql 作为底层数据库。

在我的实体中,我有一个类,其中包含在 Roo 中生成Detection的 tstampjava.util.Date字段,如下所示:

entity jpa --class ~.data.Detection
...
field date --fieldName tstamp --type java.util.Date
...
finder add findDetectionsByTstampBetween

(执行后当然选择了finder方法finder list

在我的控制器代码中,有时我会调用:

List<Detection> detections = Detection.findDetectionsByTstampBetween(from, to).getResultList(); 

其中 from 和 to 是两个有效的java.util.Date(s)。但是,在测试样本数据时(在确保给定的 from,to 返回列表不应该为空之后),我得到了一个空列表并调查了原因。

我在 tomcat 日志中发现 Hibernate 正在生成以下 SQL:

Hibernate: select detection0_.id as id1_3_, ...etc..., detection0_.tstamp as tstamp4_3_ from detection detection0_ where detection0_.tstamp>=?

我希望 where 子句应该包含一个尾随“ AND detection0_.tstamp<=?”,检查其他日期范围限制。我查看了生成的Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp)方法Detection_Roo_Finder.aj,实际上“AND”存在于对 createQuery 的调用中。

public static TypedQuery<Detection> Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp) {
        if (minTstamp == null) throw new IllegalArgumentException("The minTstamp argument is required");
        if (maxTstamp == null) throw new IllegalArgumentException("The maxTstamp argument is required");
        EntityManager em = Detection.entityManager();
        TypedQuery<Detection> q = em.createQuery("SELECT o FROM Detection AS o WHERE o.tstamp BETWEEN :minTstamp AND :maxTstamp", Detection.class);
        q.setParameter("minTstamp", minTstamp);
        q.setParameter("maxTstamp", maxTstamp);
        return q;
}

知道什么可能导致问题吗?

4

1 回答 1

0

我终于找到了这个谜题的解决方案,事实证明,这个问题与 JPA 无关。

问题在于对持久层的调用被插入到具有以下映射的 Rest 服务控制器中:

@ResponseBody
@RequestMapping(value="/detections", method=RequestMethod.GET, params="from, to" )
public Object getDetectionsInRange(
        @RequestParam(required=true) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm") final Date from,
        @RequestParam(required=true) @DateTimeFormat(pattern="yyyy-MM-dd HH:mm") final Date to
        ) 
{
    ...
    List<Detection> detections = Detection.findDetectionsByTstampBetween(from, to).getResultList(); 
    ...
}

错误出现在params=参数的定义中@RequestMapping,正确的格式如下:

@RequestMapping(value="/detections", method=RequestMethod.GET, params={"from", "to"}  )

这个错误导致了另一个版本的控制器方法/detections。在第二个版本中,我调用了一个不同的查找器方法,它似乎在 Hibernate 中生成了错误的 SQL。

@ResponseBody
@RequestMapping(value="/detections", method=RequestMethod.GET  )
public Object getDetections(
        @RequestParam(required=false, defaultValue="0") int days,
        @RequestParam(required=false, defaultValue="0") int hours,
        @RequestParam(required=false, defaultValue="0") int minutes
        ) 
{
    ...
    List<Detection> detections = Detection.findDetectionsByTstampGreaterThanEquals( ... ).getResultList(); 
    ...
}
于 2015-04-15T13:03:33.020 回答