QueryDSL: generate Predicate from PathBuilder

querydsl

Solution

You should use it like this

// entityClass is the entity type, not the Q-type
Class<?> entityClass = Class.forName(...)
// "entity" is the variable name of the path
PathBuilder<?> entityPath = new PathBuilder(entityClass, "entity"); 
// use getString to get a String path
Predicate predicate = entityPath.getString("property").like("a%");

Problem

How to replace the following method that uses the generated Q* class and java reflexion with a PathBuilder? ``` // member vars: T operand; // can be a BigDecimal or a String String tableName; String fieldName; String methodName; public Predicate asPredicate() { Class<?> tableClazz = Class.forName("foo.bar.database.model.Q"+ WordUtils.capitalize(tableName)); Object tableObj = tableClazz.getConstructor(String.class).newInstance(tableName +"1000"); Field colField = tableClazz.getDeclaredField(fieldName); Object colObj = colField.get(tableObj); Class classParam = Object.class; if(methodName.matches(".*like"){ classParam = String.class; } // method name is one of eq, ne, like... Method m = colObj.getClass().getMethod(methodName, classParam ); return (Predicate) m.invoke(colObj, operand); } ``` this works well but I was advised to use PathBuilder instead in an answer to my other question https://stackoverflow.com/questions/15269845/querydsl-extract-table-name-from-predicate-booleanexpression-object) which would also remove the awkward newInstance(tableName +"1000"). ``` PathBuilder<?> entityPath = new PathBuilder("foo.bar.database.model.Q"+ WordUtils.capitalize(tableName), "entity"); // what does the second param stand for? PathBuilder relation = entityPath.get(fieldName); // ??? ``` two problems: 1) I can call eq() or ne() on relation now but not like(), notLike() 2) how do I get colObj so that I can use java reflection colObj.getClass().getMethod(...) solution: Thanks to Timo's answer I have ditched the reflexion altogether except for the two instanceof conditions and use this code now: ``` tableClazz = Class.forName("foo.bar.database.model."+ WordUtils.capitalize(tableName)); PathBuilder<?> entityPath = new PathBuilder(tableClazz, tableName +"1000"); Predicate predicate = null; if(operand instanceof String){ StringPath path = entityPath.getString(fieldName); switch(type){ case EQ: predicate = path.eq((String) operand); case CONTAINS: predicate = path.like("%" + operand +"%"); break; // snip BEGINS WITH, ENDS WITH } }else if(operand instanceof BigDecimal){ assert(type.equals(Type.EQ)); NumberPath<BigDecimal> path = entityPath.getNumber(fieldName, BigDecimal.class); predicate = path.eq((BigDecimal) operand); } if(negation){ return predicate.not(); } return predicate; ```

Original source