我正在使用动态过滤器过滤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)
...
答案 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(...);
}
这样,您就可以进行合理的动态实施。