Критерии - это ограничивающий фактор: он позволяет выбрать только корневую сущность или скаляры. А поскольку у вас нет обратной связи (от адреса к человеку), это невозможно сделать простым способом с помощью критериев.
Я считаю HQL гораздо более гибким и гораздо более читабельным. Критерии полезны, когда запрос должен быть динамически составлен, но в этом случае использовать HQL-запрос просто:
select a from Person p inner join p.addresses a where p.id = :personId
Это на самом деле выполнимо в Criteria, но для этого нужен запрос, который менее эффективен и прост: что-то вроде
select a from Address a where a.id in (select a2.id from Person p inner join p.addresses a2 where p.id = :personId)
переведено в критерии.
Это было бы:
Criteria criteria = session.createCriteria(Address.class, "a");
DetachedCriteria dc = DetachedCriteria.forClass(Person.class, "p");
dc.createAlias("p.addresses", "a2");
dc.add(Restrictions.eq("p.id", personId);
dc.setProjection(Projections.property("a2.id"));
criteria.add(Subqueries.propertyIn("a.id", dc));
Как видите: менее читабелен, намного длиннее и менее эффективен.