Интересно обитают ли здесь жабакоеры. У меня сегодня возникла потребность выполнении одного запроса через Hibernate Criteria. Ситуация примерно следующая:
Есть entity Person содержащий общие данные о человеке. На него через @ManyToOne смотрит куча других сущностей, а вот в нём нету встречного маппинга через @OmeToMany(mappedBy="...") и не будет. Мне нужно выполнить запрос который содержит LEFT JOIN на другие сущности, но запрос в данном месте необходимо сконструировать через Hibernate Criteria API (это lazy loading paginated список с нетривиальными фильтрами которые собственно и строятся через Criteria API). Если бы был встречный маппинг я бы использовал DetachedCriteria.addAlias("joinedAlias","reverseMappingField",DetachedCriteria.LEFT_JOIN), а как сделать то же самое если встречного маппинга нет?
Для примера можно представить такую ситуацию она близка к тому что нужно получить в одном из фильтров:
@Entity @Table(name="person")
class Person {
@Id @GeneratedValue @Column(name="id") private int id;
....
}
@Entity @Table(name="user")
class User {
@Id @GeneratedValue @Column(name="id") private int id;
@NotNull @Column(name="login",unique=true) private String login;
@Column(name="pass") private String pass;
@NotNull @Column(name="enabled") private boolean enabled;
@ManyToOne @JoinColumn(name="person",unique=true) private Person person;
....
}
Нужно отфильтровать людей которые не могут входить в систему (тех у кого вообще нет юзверя или у которых юзверь заблокирован). Соответствующий SQL зпрос пишется легко:
SELECT p.* FROM person p LEFT JOIN user u ON u.person=p.id WHERE u.enabled=FALSE OR u.id IS NULL
Как добиться того же через Criteria?
Пользователь решил продолжить мысль 17 Июня 2010, 08:08:07:
После продолжительного гугления пришёл к выводу, что то, что я хочу сделать, нужно делать по другому, используя IN и подзапрос в условиях отбора:
SELECT p.* FROM person p WHERE p.id NOT IN (SELECT u.person FROM user u WHERE u.enabled=TRUE)
Такой запрос уже можно переложить на Criteria:
DetachedCriteria subquery = DetachedCriteria.forClass(User.class);
subquery.setProjection(Projections.property("person.id"));
subquery.add(Restrictions.eq("enabled",true));
DetachedCriteria criteria = DetachedCriteria.forClass(Person.class);
criteria.add(Property.forName("id").in(subquery));