我正在JPA Criteria之上构建一个高度通用的查询机制。我得到一个描述查询的XML作为输入,如下所示:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<Criteria xmlns='criteria' maxResults='2'>
<Expression>
<CompareRestriction propertyType='Date' operator='GREATER_THAN_OR_EQUALS' propertyName='deliveryDate'>2010-07-02</CompareRestriction>
<CompareRestriction propertyType='Float' operator='GREATER_THAN_OR_EQUALS' propertyName='weight'>10f</CompareRestriction>
<Restriction operator='NOT_NULL' propertyName='maxDiameter'/>
<LogicalExpression operator='OR'>
<LeftHandSideCompare propertyType="Integer" operator="EQUALS" propertyName="weight">31</LeftHandSideCompare>
<RightHandSide operator='NOT_NULL' propertyName='lastChangedDate'/>
</LogicalExpression>
<LogicalExpression operator='OR'>
<LeftHandSideCompare propertyType="Integer" operator="EQUALS" propertyName="weight">31</LeftHandSideCompare>
<RightHandSide operator='NOT_NULL' propertyName='lastChangedDate'/>
</LogicalExpression>
</Expression>
<Order propertyName='deliveryDate' type='DESC'/>
</Criteria>
我解析这个东西并构建相应的标准。目前我遇到的问题是比较运算符(&lt;,&gt;,&lt; =,=&gt;),因为我处理不同的数字类型:我有Float,Integer或Long值的字段。因此,当我映射时,我会做这样的事情:
switch (leftHandSideCompareRestriction.getOperator().value()) {
...
case "LESS_THAN" : innerPredicates.add(criteriaBuilder.gt(rootQuery.<Number>get(propName), NumberUtils.createNumber((value))));
case "LESS_THAN_OR_EQUALS" : innerPredicates.add(criteriaBuilder.gt(rootQuery.<Number>get(propName), NumberUtils.createNumber(value)));
...
}
NumberUtils是apache commons NumberUtils utility class
根据提供的输入(Float,Integer,Long或Double)返回数值类型。现在我需要一种机制来为
提供类型rootQuery<T>.get(propName)
在运行时,否则JPA抱怨我提供了一个Float而不是Integer,反之亦然。我尝试了几件事情,现在我有点想法了。我非常感谢和思考,想法,建议如何以健壮的方式实现这一目标。
答案 0 :(得分:0)
我似乎最初错过了一些东西 - 我不确定如何。在不同的部分存在某种问题。所以,做这样的查询:它肯定会起作用。我尝试了以下类型:
Integer
Float
它按预期用于以下操作:&gt;,&lt;,&lt; =,=&gt;。总之,使用Number和NumberUtils以非常优雅的方式修复了这个问题,因为NumberUtils创建了适当的类型,JPA占用了Number的层次结构的顶部。