Хотя ответ, данный Джонкарлом, был принят, он не выглядит правильным для меня.JavaDocs для CriteriaQuery.where () говорят:
Измените запрос, чтобы ограничить результат запроса в соответствии с указанным логическим выражением.Заменяет ранее добавленные ограничения, если таковые имеются.
Насколько я понимаю, каждая из следующих строк (с указанием ограничений) будет отменять ограничения, данные ранее:
criteria.where(builder.like(langJoin.get(Language_.locale), locale));
criteria.where(builder.like(pRoot.get(Person_.name), name));
criteria.where(builder.between(pRoot.get(Person_.time), startDate, endDate));
Это означает, что в конце останется только последнее ограничение (между начальной и конечной датой).
Поэтому я предлагаю следующие модификации ответа Джонарла:
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Person> criteria = builder.createCriteria(Person.class);
Root<Person> pRoot = criteria.from(Person.class);
Join<Person, Language> langJoin = criteria.join("language", JoinType.LEFT);
Predicate[] restrictions = new Predicate[] {
builder.like(langJoin.get(Language_.locale), locale),
builder.like(pRoot.get(Person_.name), name),
builder.between(pRoot.get(Person_.time), startDate, endDate)
};
criteria.where(builder.and(restrictions));
criteria.orderBy(builder.asc(pRoot.get(Person_.name)));
Однако этот код выглядит действительно безобразно!Пожалуйста, не стесняйтесь редактировать, если это не так, и комментируйте, если вы видите лучшее решение!Я был бы изящен!