Из того, что я помню, это должно быть представление вашего первого запроса.
Редактировать: сейчас протестировано
Я не могу проверить это прямо сейчас, так как моя база данных не отвечает, поэтому, если она не работает, я отредактирую ответ позже.
Используйте ParameterExpression для непостоянных параметров, чтобы убедиться, что сервер может повторно использовать запрос. В противном случае необходимо проанализировать и перепланировать каждый новый запрос.
Но в этом случае выражения ParamterExpression, похоже, не работают правильно, возможно, это проблема Hibernate (для проверки я использовал 5.4.2.Final).
Ps .:
Вам следует избегать использования ключевых слов «sql» для идентификаторов таблиц, поэтому вместо именования таблицы «table» используйте что-то еще.
SELECT * FROM table AS t WHERE id = (SELECT MAX(id) FROM table AS t WHERE t.element_id = 354 AND (name <> 'foo' OR (name = 'bar' AND event = 'foo')));
CriteriaQuery<Table> criteriaQuery = cb.createQuery(Table.class);
Root<Table> root = criteriaQuery.from(Table.class);
Subquery<Integer> sub = criteriaQuery.subquery(Integer.class);
Root<Table> subRoot = sub.from(Table.class);
criteriaQuery.where(
cb.equal(subRoot.get(Table_.element_id), 354),
cb.or(cb.notEqual(subRoot.get(Table_.name), "foo"),
cb.and(cb.equal(subRoot.get(Table_.name), "bar"),
cb.equal(subRoot.get(Table_.event), "foo"))));
sub.select(cb.max(subRoot.get(Table_.id)));
criteriaQuery.where(cb.equal(root.get(Table_.id), sub));
criteriaQuery.select(root);
List<Table> result =
entityManager.createQuery(criteriaQuery)
.getResultList();