Chociaż odpowiedź udzielona przez johncarl została przyjęta, nie wygląda mi to na poprawne. W Javadocs do CriteriaQuery.where() powiedzieć:
ją zmodyfikować, aby ograniczyć wynik zapytania według określonej logicznej ekspresji. Zastępuje wcześniej dodane ograniczenia, o ile takie istnieją.
Jak rozumiem, każdy z kolejnych wierszy (ograniczenia dające) zastąpi ograniczeń podanych poprzednio:
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));
Oznacza to, że w końcu tylko ostatnie ograniczenie (między data początkowa i końcowa) pozostanie.
threfore Proponuję następujące modyfikacje odpowiedź johncarl za:
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)));
Jednak ten kod wygląda naprawdę brzydki! Zmodyfikuj je, jeśli są błędne i skomentuj je, jeśli znajdziesz lepsze rozwiązanie! Byłbym wdzięczny!
Czy możesz pokazać swoje implementacje dla osoby i języka? –