2013-02-24 1 views
0

Привет Я пытаюсь выбрать записи из одной таблицы, которая не имеет записей в подключенной таблице многих ко многим со специфическими значениями.Выберите записи, которые не имеют конкретных записей в объединенной таблице

Поясню на таблицах примера:

documentation: 
id_documentation 
irrelevant_data 

user: 
id_user 
irrelevant_data 


documentation_user: 
id_documentation 
id_user 
role 

То, что я хочу добиться того, чтобы выбрать каждую документацию, которая не имеет пользователя в определенной роли. Есть идеи?

Основная проблема заключается в том, что я использую java CriteriaBuilder для создания запроса, поэтому использование подзапросов невозможно (я думаю).

+0

Возможно, это ... Есть ли возможность добавить дополнительные условия присоединения для добавления в предложение ON? Например: выберите * из документации d left join documentation_user du ON d.id_documentation = du.id_documentation И du.role = 2; – J33nn

+1

Да, начиная с Hibernate 3.5.0 вы можете. см. [это исправление] (https://hibernate.onjira.com/browse/HHH-2308) – dan

+0

Не могли бы вы рассказать мне, как достичь этого с помощью CriteriaBuilder? Корень <Документация> u = select.from (Documentation.class); Join dul = u.join ("documentationUserCollection", JoinType.LEFT); – J33nn

ответ

0

Основная проблема не существует. Критерии API имеют SubQuery. Сам запрос выбирает экземпляры Пользователя и использует конструкцию notin для ограничения результатов, основанных на подзапросе. Подзапрос выбирает всех пользователей, которые подключены к документу с определенной ролью через DocumentationUser.

+0

Лучше всего лежать в join documentation_user с дополнительными критериями и проверять, является ли id_user нулевым: выберите * из документации d left join documentation_user du on d.id_documentation = du.id_documentation и du.role = 2, где du.id_user равно null; – J33nn

+0

Но я еще не знаю, как добавить дополнительные условия для присоединения к CriteriaBuilder. – J33nn

+0

Невозможно добавить дополнительные условия соединения в API критериев. –

0

Вы можете добавить ограничения на свое левое соединение, используя: createAlias(java.lang.String, java.lang.String, int, org.hibernate.criterion.Criterion) метод, см. API.

Отметьте this ответ на пример о том, как использовать левое соединение с критериями.

0

попробовать что-то вроде этого (код не тестировался):

CriteriaQuery<Documentation> cq = cb.createQuery(Documentation.class); 
Root<Documentation> u = cq.from(Documentation.class); 
Subquery<Integer> sq = cq.subquery(Integer.class); 
Root<User> su = sq.from(User.class); 
sq.select(su.get("id_user")); 
Join<User, DocumentationUser> du = su.join("documentationUserCollection"); 
sq.where(cb.equals(du.get("role"), "mySpecificRole")); 
cq.where(cb.not(cb.in(u.get("id_user")).value(sq))); 

Смотрите также this useful answer on SO.