Примеры объектов:
@Entity
public class Employee {
@Id
@Column(name="EMP_ID")
private long id;
...
@OneToMany(mappedBy="owner")
private List<Phone> phones;
...
}
@Entity
public class Phone {
@Id
private long id;
...
@ManyToOne
@JoinColumn(name="OWNER_ID")
private Employee owner;
...
}
У меня есть универсальный класс, в котором запросы генерируются на основе типа объекта:
public class Repository<T>
{
private Class<T> type;
public List<T> select(String property, Object value) {
EntityManager em = getEntityManager();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<T> q = cb.createQuery(type);
Root<T> root = q.from(type);
Path<Object> path = root.get(property);
query.where(path.in(value));
query.select(q.select(root));
TypedQuery<A> query = em.createQuery(q);
return query.getResultList();
}
}
Я хочу сгенерировать следующий запрос
SELECT * FROM PHONE WHERE OWNER_ID = ?
, выполнив
Repository<Phone> repository;
List<Phone> phones = repository.select("owner.id", 1);
, но это не работает, потому что "owner.id" не может быть найден.Хотя утверждение
em.createQuery("SELECT p FROM Phone p WHERE p.owner.id = :id")
действительно работает.
Как я могу создать универсальный CriteriaQuery на основе типа T
, в результате чего указанный оператор не будет знать тип Employee
?