Let's say I have a generated Entity like this:
public class QCandidate extends EntityPathBase<Candidate> {
public final com.avisto.candisearch.persistance.model.enums.QAvailabilityEnum availability;
public final DatePath<java.util.Date> birthDate = createDate("birthDate", java.util.Date.class);
public final NumberPath<Long> cvId= createNumber("cvId", Long.class);
public final StringPath city = createString("city");
}
My input values are the fields names ("availability","birthDate","cvId"...) and a string value that I should use to perform a 'like' with all the fields.
I want to build a query starting from the field names that:
Something like:
lower(cast(C.cvId as varchar(255))) like 'value'
for each field.
I can do this usign querydsl-sql module, but I want to achieve it using only the jpa module.
I'm not interested in the mechanism of creating the FULL 'where' clause (I know I have to use the BooleanBuilder, or at least, this is what I do in the sql version).
What I want to know is how to create the individual 'where' conditions basing on the field type.
I'm trying to use a PathBuilder but it seems that to use methods like "getString or getBoolean" you already have to know the type of the field that you are trying to extract. In my case, since I start just from the field name, I can't use these methods and I don't know how to identify the type of each field starting from the field name, so I'm stuck.
May be a bit ugly, but workable suggestion.
Note, that the number of field types that PathBuilder accepts is quite limited.
You definitely can find the field class from field name (using reflection or by maintaining a member map updated with each field).
Just implement handling for each specific type.
This can be ugly bunch of if..else
or, for more elegant solution, create Map of type handlers [class->handler], each handler implements interface method to handle specific type.
Pseudocode:
//building query
for each field
Class fieldClass = findFieldClas(.., field) //use reflection or map
PathHandler handler = handlers.get(fieldClass)
handler.process( ...)
//type handler interface
public interface Handler{
public xx process(? extends DataPathBase);
}
//specific type handler implementation
public class BooleanHandler implements Handler{
public xx process(? extends DataPathBase path){
BooleanPath bPath = (BooleanPath)path;
...
}
//intitialize handlers map singleton or a factory in advance
handlers.put(BooleanPath.class, new BooleanHandler());
...
Note this is a generic solution if you have many classes. If you have only one specific class, you can just create a permanent map of fieldName->Handler and avoid lookup for the field class.
Again, this is by no means a pretty solution, but should work.