My RefineByBasicTaskType should add the same criteria for different CriteriaQuery types. T could be a Task or a Appointment. The only difference is, that there is no join needed if T is a Task.
How can I use my RefineByBasicTaskType class for multiple types?
public class RefineByBasicTaskType<T> extends AbstractRefinement<T> {
private BasicTaskType basicTaskType;
public Predicate addCriteriaQuery(CriteriaQuery<T> criteria, CriteriaBuilder builder, Root<T> taskRoot) {
if (T instanceof Task) {
return refineByBasicTaskType(builder,
taskRoot);
}
return refineByBasicTaskType(builder,
fetchOrCreateFirstJoin(taskRoot,"task"));
}...
From a proper object oriented point of view you are trying to re-invent mechanisms that are already possible with inheritance:
public abstract class RefineByBasicTaskType<T> extends AbstractRefinement<T> {
public abstract Predicate addCriteriaQuery(CriteriaQuery<T> criteria, CriteriaBuilder builder, Root<T> root);
}
public class RefineByTask extends RefineByBasicTaskType<Task> {
@Override
public Predicate addCriteriaQuery(CriteriaQuery<Task> criteria, CriteriaBuilder builder, Root<Task> root) {
return refineByBasicTaskType(builder, root);
}
}
public class RefineByWhatever extends RefineByBasicTaskType<Whatever> {
@Override
public Predicate addCriteriaQuery(CriteriaQuery<Whatever> criteria, CriteriaBuilder builder, Root<Whatever> root) {
return refineByBasicTaskType(builder, fetchOrCreateFirstJoin(root, "task"));
}
}
Edit: If you don't want to use inheritance you should be able to get the Java type from the Root
object so you could also replace your if
-statement with:
if (taskRoot.getJavaType().equals(Task.class)) {
// ...
}