Question

I use a Abstract Base class with generic implementation to access my database with JPA. I also use the Entity Meta Model.

public List<PersonEntity> findByCode(String code) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<PersonEntity> cq = cb.createQuery(PersonEntity.class);
    Root<PersonEntity> root = cq.from(PersonEntity.class);

    Predicate predicate = cb.equal(root.get(PersonEntity_.code), code);
    cq.where(predicate);

    TypedQuery<PersonEntity> query = entityManager.createQuery(cq);
    List<PersonEntity> list = new ArrayList<>();
    return query.getResultList();
}   

I want to move this to a generic base class, since this peace of code is use a lot of times. How do I check if there is a "code"? Not all classes have one.

public List<E> findByCode(String code) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<E> cq = cb.createQuery(entityClass);
    Root<E> root = cq.from(entityClass);

    //here is my problem: how to check if there is a "code"?
    // Most classes have one, but not all.
    Predicate predicate = cb.equal(root.get(PersonEntity_.code), code);
    cq.where(predicate);

    TypedQuery<E> query = entityManager.createQuery(cq);
    List<E> list = new ArrayList<>();
    return query.getResultList();
}
Was it helpful?

Solution

You should probably declare an interface (with better name):

public interface Codeable {
    public String getCode();
}

And then declare the method as such:

public List<E implements Codeable> findByCode(String code, Class<E> clazz) {
    CriteriaBuilder cb = entityManager.getCriteriaBuilder();
    CriteriaQuery<E> cq = cb.createQuery(entityClass);
    Root<E> root = cq.from(entityClass);

    //here is my problem: how to check if there is a "code"?
    // Most classes have one, but not all.
    Predicate predicate = cb.equal(root.get(PersonEntity.getCode()), code);
    cq.where(predicate);

    TypedQuery<E> query = entityManager.createQuery(cq);
    List<E> list = new ArrayList<>();
    return query.getResultList();
}

You pass to the parameter clazz you class type (in order for the compiler to know which type to actually use in the query and which type to return):

List<PersonEntity> persons = dao.findByCode("someCode", PersonEntity.getClass());

P.S

I also changed the .code to .getCode() in order to comply with the interface.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top