'Predicate on a field of an entity class which is type of a parent class and filter on fields of its children

In the entity class A there is a field of type P1 named as p. Class P2 and P3 is extended from P1. In the predicate I want to filter the result based on a field of class P2. How can I do this?

public class A {
    private P1 p;
}

public class P1 {
}

public class P2 extends P1 {
    private String s;
}

public class P3 extends P1 {
    private String u;
}

public interface ARepository extends CrudRepository<A, Long>, QuerydslPredicateExecutor<A>, QuerydslBinderCustomizer<QA> {
    @Override
    default void customize(QuerydslBindings bindings, QA a) {
        bindings.bind(String.class).first((SingleValueBinding<StringPath, String>) StringExpression::containsIgnoreCase);
    }
    default Page<A> findByFilter(AFilter filter, Pageable pageable) {
        Predicate predicate = new APredicatesBuilder().build(filter);
        return findAll(predicate, pageable);
    }
}

class APredicatesBuilder {
    private List<BooleanExpression> predicates = new ArrayList<>();
    private addPredicate(BooleanExpression predicate) {
        if (null != predicate) {
            predicates.add(predicate);
        }
    }
    BooleanExpression build(AFilter filter) {
        QA a = QA.a;
        if (filter.getS() != null) {
            addPredicate(a.p.s.eq(filter.getS()); // This is not possible. How to do it?
        }
        BooleanExpression result = null;
        if (!predicates.isEmpty()) {
            result = predicates.get(0);
            for (int i = 1; i < predicates.size(); i++) {
                result = result.and(predicates.get(i));
            }
        }
        return result;
    }
}

class AFilter {
    private String s;
}

As I commented in the code, this is not possible to add predicate on A and filter the results based on field s in class P2.



Solution 1:[1]

This is an issue with your class hierarchy: A has a field p of type P1 but the field s does only exist in class P2. I would recomment to migrate p to type P2 or to move s to parent class P1.

At the end, this has nothing to do with querydsl and happen in the same way with pure java.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Stefan Schmidt