Предикат «IN» для построителя критериев JPA при ошибке внешнего ключа: при сравнении объектов могут использоваться только операторы equal () или notEqual () - PullRequest
1 голос
/ 18 апреля 2011

Я хочу выбрать список ссылок на файлы из таблицы, посмотрев, у каких пользователей есть права на получение этого файла. Для этого у меня есть 3 таблицы, таблица файлов, таблица контроля доступа и таблица пользователей.

Я использую JPA и Criteriabuilder (поскольку задействовано больше таблиц, и мне необходимо создать запрос динамически, я опускаю другие таблицы и предикаты из этого вопроса для удобства чтения).

Следующий код работает

CriteriaBuilder queryBuilder = em.getCriteriaBuilder();                         
CriteriaQuery<File> queryDefinition = queryBuilder.createQuery(File.class);   
Root<File> FileRoot = queryDefinition.from(File.class);                      
List<Predicate> predicateList = new ArrayList<Predicate>();    

Predicate userPredicate = FileRoot .join("FileAccesControlCollection").join("userId").get("usersId").in(loggedInUser.getUsersId());

predicateList.add(userPredicate );               

queryDefinition.where(predicateArray).distinct(true);                      
Query q = em.createQuery(queryDefinition);
List<Files> results = (List<Files>) q.getResultList(); 

Для пользователя userpredicate я хочу пропустить последнее соединение с таблицей пользователей, потому что идентификатор, по которому я хочу фильтровать, уже присутствует в таблице FileAccesControlCollection, а соединение - это дорогостоящая вычислительная операция базы данных.

Я попытался сделать это:

Predicate userPredicate = FileRoot .join("FileAccesControlCollection").get("usersId").in(loggedInUser.getUsersId());

Но я предполагаю, что, поскольку значение userId в классе сущности FileAccesControlCollection является ссылкой на внешний класс для ссылки на класс Users, я получаю следующую ошибку:

Exception Description: Object comparisons can only use the equal() or notEqual() operators.  Other comparisons must be done through query keys or direct attribute level comparisons. 

Есть ли способ, используя сущность loggedInUser или его Id, фильтровать файлы, просто присоединяя класс File к классу FileAccesControlCollection и фильтруя по внешнему ключу userId? Я новичок в JPA, и использование Google привело меня к большому количеству страниц, но неясный ответ на вопрос, который мне кажется возможным.

Ответы [ 2 ]

2 голосов
/ 19 апреля 2011

Значит, userId отображается как OneToOne?Затем вы можете сделать,

get("userId").get("id").in(...)

Вы также можете добавить QueryKey в EclipseLink, используя DescriptorCustomizer для поля внешнего ключа, а затем использовать его в запросе,

get("userFk").in(...)
0 голосов
/ 26 сентября 2013

попробуйте это:

Predicate userPredicate = FileRoot.join(FileAccesControlCollection.class).join(Users.class).get("{id field name in class Users}").in(loggedInUser.getUsersId());

удачи.

...