Вы должны основать свой запрос на entity2.details
. Поскольку API критериев является типобезопасным, он обнаруживает, что entity1 не имеет поля с именем «details»
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery q = builder.createQuery();
Root r = q.from(Entity2.class); // Must use subclass as root
q.select(r);
q.where(builder.gt(r.join("details", JoinType.LEFT).get("quantity"), 1));
Поскольку Entity2 расширяет Entity1, вы можете безопасно преобразовать результаты в родительский тип. Например:
CriteriaQuery<Entity1> q = builder.createQuery(Entity1.class);
Root r = q.from(Entity2.class); // Must use subclass as root
вернет список Entity1
CriteriaQuery<Entity2> q = builder.createQuery(Entity2.class);
Root r = q.from(Entity2.class); // Must use subclass as root
вернет список Entity2
EDIT:
Я думаю, что неправильно понял цель здесь. Если вы хотите, чтобы все Entity1 НЕ БЫЛИ, если они Entity2 с details.quantity <= 1, вам нужно сделать больше. </p>
Вы не можете использовать левое соединение от Entity1Detail к Entity1, потому что это не является строго типобезопасным. Вместо этого вам нужно как-нибудь присоединить Entity2 к Entity1Detail. Вероятно, лучший инструмент для использования здесь - это коррелированный подзапрос .
CriteriaQuery<Entity1> q = builder.createQuery(Entity1.class);
Root<Entity1> ent1 = q.from(Entity1.class);
SubQuery<Entity2> subq = q.subquery(Entity2.class);
Root<Entity2> ent2 = subq.from(Entity2.class);
Path<Integer> quantity = ent2.join("details", JoinType.LEFT).get("quantity");
Predicate lessThan = builder.lte(quantity,1);
Predicate correlatedSubqJoin = cb.equal(ent1,ent2)
subq.where(lessThan, correlatedSubqJoin);
q.select(ent1);
q.where(builder.exists(subq).not());
API критериев не знает, что вы наследуете одну таблицу, поэтому вы должны написать свои запросы для всех стратегий наследования, включая стратегию наследования Joined.