Я пытался помочь другому пользователю с вопросом о том, как преобразовать SQL в критерии, когда я наткнулся на эту проблему: Как преобразовать SQL-запрос с использованием CriteriaQuery
Для некоторыхпричина ParameterExpression
не работает с подзапросами.Я использовал Hibernate 4.5.2.Final для этого.
Интересно, действительно ли это ошибка, или вам нужно указать ParameterExpressions
для подзапросов по-другому.
Сущность:
@Entity
@Table(name="test")
public class Test {
@Id
private int id;
private String event;
private String name;
private int element_id;
// + getter & setter
}
Запрос критерия
EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory( "test" );
EntityManager entityManager = entityManagerFactory.createEntityManager();
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Test> criteriaQuery = cb.createQuery(Test.class);
Root<Test> root = criteriaQuery.from(Test.class);
Subquery<Integer> sub = criteriaQuery.subquery(Integer.class);
Root<Test> subRoot = sub.from(Test.class);
ParameterExpression<Integer> elementId = cb.parameter(Integer.class);
ParameterExpression<String> name1 = cb.parameter(String.class);
ParameterExpression<String> name2 = cb.parameter(String.class);
ParameterExpression<String> event = cb.parameter(String.class);
criteriaQuery.where(
cb.equal(subRoot.get(Test_.element_id), elementId),
cb.or(cb.notEqual(subRoot.get(Test_.name), name1),
cb.and(cb.equal(subRoot.get(Test_.name), name2),
cb.equal(subRoot.get(Test_.event), event))));
sub.select(cb.max(subRoot.get(Test_.id)));
criteriaQuery.where(cb.equal(root.get(Test_.id), sub));
criteriaQuery.select(root);
List<Test> result =
entityManager.createQuery(criteriaQuery)
.setParameter(elementId, 354)
.setParameter(name1, "foo")
.setParameter(name2, "bar")
.setParameter(event, "foo")
.getResultList();
При выполнении кода выше обычного запроса (например, только подзапроса) он работает, но с подзапросом выдается исключение:
Исключение в потоке "main" java.lang.NullPointerException
в org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.setParameter (CriteriaQueryTypeQueryAdapter.j22:39 или at. Org. 392)hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.setParameter (CriteriaQueryTypeQueryAdapter.java:61)
at .setParameter (elementId, 354)>
при отладке я вижу кодв org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter #licitParameterInfoMap, но это пустое значение, поэтому возвращается ноль и вызывается NPE.
Редактировать :
Это не обсуждение преимуществ ParameterExpressions
, например , с использованием ParameterExpression по сравнению с переменной в JPA Criteria API , но вместо этогоконкретный вопрос о том, как использовать ParameterExpressions для подзапросов, чтобы hibernate мог справиться с этим.Возможно, ответ на мой вопрос заключается в том, что использование является правильным и что только реализация является ошибочной.