我正在编写一个规则查询解析器,以通过if-then-else块进行解析,以生成用于获取结果集的类型化查询。 这是我准备的查询示例:
select New com.sb.rule.service.dto.FoundObject(shipment.id)
from Shipment shipment
left join shipment.shipmentLines shipmentLines
left join shipmentLines.itemDetail itemDetail
left join shipment.fromAddress fromAddress
left join shipment.toAddress toAddress
where (
(
( shipment.createDate = java.time.LocalDate.now().minusDays(1) )
and
( itemDetail.uom = 'EACH' )
and
( shipmentLines.itemNum = 'I1' )
and
( shipmentLines.shipDate = java.time.LocalDate.now().plusDays(5) )
)
and
(
( fromAddress.country = 'IN' )
or
( toAddress.country = 'IN' )
)
)
我什至尝试删除其他括号以将查询更改为:
select New com.sb.rule.service.dto.FoundObject(shipment.id) from com.sb.rule.domain.Shipment shipment left join shipment.shipmentLines shipmentLines left join shipmentLines.itemDetail itemDetail left join shipment.fromAddress fromAddress left join shipment.toAddress toAddress
where ( shipment.createDate = java.time.LocalDate.now().minusDays(1) and itemDetail.uom = 'EACH' and shipmentLines.itemNum = 'I1' and shipmentLines.shipDate = java.time.LocalDate.now().plusDays(5) )
and ( fromAddress.country = 'IN' or toAddress.country = 'IN' )
但是我仍然遇到相同的错误。
执行此查询时:
log.debug("Sql Query being executed : " + sqlQuery);
TypedQuery<FoundObject> query = entityManager.createQuery(sqlQuery.toString(), FoundObject.class);
Set<FoundObject> foundObjectSet = new HashSet<FoundObject>(query.getResultList());
log.debug("Returning : " + foundObjectSet.toString());
我得到以下异常:
java.lang.IllegalArgumentException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected AST node: ( near line 1, column 339 [select New com.sb.rule.service.dto.FoundObject(shipment.id) from com.sb.rule.domain.Shipment shipment left join shipment.shipmentLines shipmentLines left join shipmentLines.itemDetail itemDetail left join shipment.fromAddress fromAddress left join shipment.toAddress toAddress where (( ( shipment.createDate = java.time.LocalDat e.now().minusDays(1) ) and ( itemDetail.uom = 'EACH' ) and ( shipmentLines.itemNum = 'I1' ) and ( shipmentLines.shipDate = java.time.LocalDate.now().plusDays(5) ) ) and ( ( fromAddress.country = 'IN' ) or ( toAddress.country = 'IN' ) ))]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:133)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157)
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:670)
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:686)
at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305)
at com.sun.proxy.$Proxy182.createQuery(Unknown Source)
at com.sb.rule.service.business.EvaluateRule.queryRuleDefinition(EvaluateRule.java:146)
任何关于我在做什么错的想法都将受到赞赏。
答案 0 :(得分:0)
您可能已经意识到解析器在这里失败,将输入分割为错误:
java.time.LocalDat e.now().minusDays(1) )
因此,也许您可以尝试使用此经过修剪的查询:
select New com.sb.rule.service.dto.FoundObject(shipment.id) from com.sb.rule.domain.Shipment shipment left join shipment.shipmentLines shipmentLines left join shipmentLines.itemDetail itemDetail left join shipment.fromAddress fromAddress left join shipment.toAddress toAddress where ( shipment.createDate = java.time.LocalDate.now().minusDays(1) and itemDetail.uom = 'EACH' and shipmentLines.itemNum = 'I1' and shipmentLines.shipDate = java.time.LocalDate.now().plusDays(5) ) and ( fromAddress.country = 'IN' or toAddress.country = 'IN' )
答案 1 :(得分:0)
问题是您没有使用参数化查询,而是尝试将参数直接添加到查询中。
您需要用这样的名称替换参数
select New com.sb.rule.service.dto.FoundObject(shipment.id)
from Shipment shipment
left join shipment.shipmentLines shipmentLines
left join shipmentLines.itemDetail itemDetail
left join shipment.fromAddress fromAddress
left join shipment.toAddress toAddress
where
shipment.createDate = :cd
and
itemDetail.uom = :uom
and
shipmentLines.itemNum = :inum
and
shipmentLines.shipDate = :sd
and (
fromAddress.country = :fc
or
toAddress.country = :tc
)
然后将参数传递给查询:
java.time.LocalDate today = java.time.LocalDate.now();
List<FoundObject> lst = em.createQuery(hqlstring, FoundObject.class)
.setParameter("cd", today.minusDays(1))
.setParameter("uom", "EACH") // or variable, instead of constant
.setParameter("inum", "I1") // or variable, instead of constant
.setParameter("sd", today.plusDays(5))
.setParameter("fc", "IN") // or variable, instead of constant
.setParameter("tc", "IN") // or variable, instead of constant
.getResultList();
您还会使用太多不必要的圆括号