Hibernate: Criteria API: запрашивать объекты, которые не содержат указанный элемент в CollectionOfElements? - PullRequest
0 голосов
/ 25 мая 2011

Допустим, у меня есть следующие два класса; Пользователь и местоположение. Я хочу создать DetachedCriteria для запроса таблицы пользователей и вернуть всех пользователей, у которых нет местоположения с именем «xyz».

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    @CollectionOfElements
    Set<Location> locations;
}

@Entity
public class Location{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long id;

    @Column
    String name;
}

Следующий код вернет всех пользователей, у которых есть местоположение с именем «xyz»:

DetachedCriteria dc = DetachedCriteria.forClass(User.class);
dc.createCriteria("locations")
     dc.add(Restrictions.eq("name", "xyz"));

Если я перехожу на Restrictions.ne (), это не сработает, потому что вернут только тех пользователей, у которых на самом деле заданы местоположения. Кроме того, если для пользователя задано несколько местоположений, он будет дублировать этого пользователя снова и снова.

Есть идеи?

Ответы [ 2 ]

1 голос
/ 09 марта 2012

Использование сущностей Пользователь и Местоположение , как описано в исходном сообщении:

1) Проверьте, не связаны ли пустые связанные местоположения .

Junction or = Restrictions.disjunction();
or.add(Restrictions.isEmpty("locations"));

2) Создать связанный критерий для местоположений , используя LEFT_JOIN и псевдоним, который будет использоваться в ограничении " ne ",Требуется LEFT_JOIN, поэтому мы все равно получаем Пользователь записей обратно, даже если отношение location пусто.

userCriteria.createCriteria("locations", "loc", Criteria.LEFT_JOIN);
or.add(Restrictions.ne("loc.name", "xyz"));

3) Добавьте дизъюнкцию к оригиналу Пользователь критерий.

userCriteria.add(or);
0 голосов
/ 25 мая 2011

Возможно, вам понадобится комбинация Restrictions.and(), Restrictions.not(), Restrictions.or() и Restrictions.in(), чтобы заставить вашу обратную логику работать правильно.Отметьте http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/criterion/Restrictions.html - это определенно можно сделать!

Чтобы убедиться, что вы получаете только максимум User, используйте проекцию Distinct (http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/criterion/Distinct.html) через фабрику Projections.distinct()метод (http://docs.jboss.org/hibernate/core/3.5/api/org/hibernate/criterion/Projections.html)- т.е.:

dc.setProjection(Projections.distinct(Projections.property("id")));

Что-то подобное должно делать то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...