QueryDSL + PathBuilder +强制转换为字符串

时间:2015-03-30 13:28:14

标签: dynamic casting path querydsl

我正在使用动态过滤器过滤PrimeFaces DataTables。我使用Spring org.springframework.data.jpa.domain.Specification工作。现在我想使用QueryDSL来做同样的事情。

使用规范我可以使用javax.persistence.criteria.Root获取javax.persistence.criteria.Join,使用javax.persistence.criteria.Expression.as(Class<String> type)将其强制转换为字符串,最后使用javax.persistence.criteria.CriteriaBuilder.like(Expression<String> x, String pattern, char escapeChar)

如何在QueryDSL中执行相同的操作?我可以使用new PathBuilder<T>(clazz, "entity")获取PathBuilder(你真的必须在这里使用变量吗?我希望我的类是通用的...)但是com.mysema.query.types.path.PathBuilder.get(String property)返回新的PathBuilder而不是Expression。 / p>

如果我尝试使用com.mysema.query.types.path.PathBuilder.getString(String property),我会java.lang.IllegalArgumentException: Parameter value [1] did not match expected type [java.lang.Integer]

似乎我失踪的那部分是演员。 我很确定有人正在处理同样的事情。

感谢。

编辑:IllegalArgumentException的堆栈跟踪

尝试使用com.mysema.query.types.path.PathBuilder.getString(String property)在整数列中搜索文本“1” - 这就是我需要进行强制转换的地方:

Caused by: java.lang.IllegalArgumentException: Parameter value [1] did not match expected type [java.lang.Integer] at org.hibernate.ejb.AbstractQueryImpl.validateParameterBinding(AbstractQueryImpl.java:375) at org.hibernate.ejb.AbstractQueryImpl.registerParameterBinding(AbstractQueryImpl.java:348) at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:375) at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:442) at org.hibernate.ejb.QueryImpl.setParameter(QueryImpl.java:72) at com.mysema.query.jpa.impl.JPAUtil.setConstants(JPAUtil.java:44) at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:130) at com.mysema.query.jpa.impl.AbstractJPAQuery.createQuery(AbstractJPAQuery.java:97) at com.mysema.query.jpa.impl.AbstractJPAQuery.list(AbstractJPAQuery.java:240) at org.springframework.data.jpa.repository.support.QueryDslJpaRepository.findAll(QueryDslJpaRepository.java:102) ...

2 个答案:

答案 0 :(得分:1)

要获得有效条件,您需要考虑属性的类型,例如

pathBuilder.getNumber(Integer.class, property).stringValue().like(likePattern)

答案 1 :(得分:0)

我一直在研究类似的话题,直到遇到这个老问题。希望我的回答对某些人有帮助。

我认为可能的解决方案(排他性地)位于QueryDSL之外。您可以使用常见的Java反射来获取字段类型,例如

Class type = clazz.getDeclaredField(criteria.getKey()).getType();
// don't forget to catch exception if field doesn't exist ..
switch(type.getSimpleName()) {
    case "String": 
         StringExpression exp =  entityPath.getString(...);
}

这样,您就可以进行合理的动态实施。