JPA/Hibernate 在 Spring Roo 查找器方法中生成错误的 SQL
JPA/Hibernate generating wrong SQL in Spring Roo finder method
我正在开发一个 Spring Web 应用程序,其持久层包含 Spring Roo 生成的 JPA 实体,Hibernate 作为持久性提供程序,MySql 作为底层数据库。
在我的实体中,我有一个 class Detection
,在 Roo 中生成了一个 tstamp java.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_Roo_Finder.aj
中生成的 Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp)
方法,实际上 "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;
}
知道是什么导致了这个问题吗?
我终于找到了谜语的答案,事实证明,这个问题与 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();
...
}
错误在@RequestMapping
中params=
参数的定义,正确格式如下:
@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();
...
}
我正在开发一个 Spring Web 应用程序,其持久层包含 Spring Roo 生成的 JPA 实体,Hibernate 作为持久性提供程序,MySql 作为底层数据库。
在我的实体中,我有一个 class Detection
,在 Roo 中生成了一个 tstamp java.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_Roo_Finder.aj
中生成的 Detection.findDetectionsByTstampBetween(Date minTstamp, Date maxTstamp)
方法,实际上 "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;
}
知道是什么导致了这个问题吗?
我终于找到了谜语的答案,事实证明,这个问题与 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();
...
}
错误在@RequestMapping
中params=
参数的定义,正确格式如下:
@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();
...
}