Вы можете переходить к ассоциациям, используя вложенные критерии, например:
List<B> result = session.createCriteria( A.class )
.add( Restrictions.like("name","he%") )
.createCriteria( "b" )
.add( Restrictions.like("name", "he%") )
.list();
Мой «второй» ответ не для критериев, а скорее CriteriaBuilder , который я бы не рекомендовал длянебольшие случаи использования, но для случаев использования, когда запрос должен быть создан динамически с изменяющимися условиями, исходящими от пользователей или других приложений.
final CriteriaBuilder queryBuilder = getCriteriaBuilder(); // Retrieve your CriteriaBuilder here. I inject mine over CDI for example...
final CriteriaQuery<B> query = queryBuilder.createQuery( B.class ); // Type the query to it's expected end result type.
final Root<A> queryRoot = query.from( A.class ); // Select the root of the query
final Join<Object, Object> BJoin= queryRoot.join("b", JoinType.LEFT ); // "b" is the field name to use for the mapping between the root table to the joined table. In this case a.b
// The above equals "left join b on b.id = a.b.id "
// Perform a select with the Class resulting from the select and what wants to be selected.
// It is also possible to select only a field of a table but in our case we want the whole table of B to be selected.
final Selection<B> select = queryBuilder.construct( B.class, BJoin );
query.select(select); // add the select to the query
// We need to remember the ParameterExpression in order to fill the where condition.
// This acts as a typed(!) blank to later fill with the condition we want to match
final ParameterExpression<String> bName = queryBuilder.parameter(String.class);
// Define the where condition using the Path<T> you retrieve from Root or Join objects.
// This will make hibernate build the condition for the correct table like b.name
final Predicate bPredicate = queryBuilder.equal( bJoin.get("name"),bName );
query.where(bPredicate); // add the where expression to the query.
// The above equals something like "where b.name = ?"
// Compile the built query to a TypedQuery
// The EntitiyManager is also injected over CDI in my usual case.
final TypedQuery<B> builtQuery = javax.persistence.EntityManager.createQuery(query);
builtQuery.setParameter(bName,"test"); // Fill in the ? of the where condition.
final List<B> resultList = builtQuery.getResultList();
Вначале это кажется очень тяжелым и сложным, но его можно использоватьочень динамично, так как вы можете просто извлечь несколько методов из фрагмента и включить добавление нескольких, где условия, упорядочить по, сгруппировать по и т. д.