JPA CriteriaBuilder – Как использовать оператор сравнения «IN»
Не могли бы вы помочь мне, как преобразовать следующие коды в использование оператора «in» в построителе критериев? Мне нужно фильтровать, используя список / массив имен пользователей, используя «in».
Я также попытался выполнить поиск с использованием метода JPA CriteriaBuilder – «in», но не смог найти хороший результат. Поэтому я был бы очень признателен, если бы вы могли дать мне ссылки на эту тему. Благодарю.
Вот мои коды:
- Ошибка гибернации: org.hibernate.NonUniqueObjectException: другой объект с тем же значением идентификатора уже был связан с сеансом
- Перечисление карты в JPA с фиксированными значениями?
- Родные запросы JPA / Hibernate не распознают параметры
- Любые хорошие инструменты ORM для разработки Android?
- JPA - сохранение отношения от одного до большого
//usersList is a list of User that I need to put inside IN operator CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder(); CriteriaQuery criteria = builder.createQuery(ScheduleRequest.class); Root scheduleRequest = criteria.from(ScheduleRequest.class); criteria = criteria.select(scheduleRequest); List params = new ArrayList(); List<ParameterExpression> usersIdsParamList = new ArrayList<ParameterExpression>(); for (int i = 0; i < usersList.size(); i++) { ParameterExpression usersIdsParam = builder.parameter(String.class); params.add(builder.equal(scheduleRequest.get("createdBy"), usersIdsParam) ); usersIdsParamList.add(usersIdsParam); } criteria = criteria.where(params.toArray(new Predicate[0])); TypedQuery query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria); for (int i = 0; i < usersList.size(); i++) { query.setParameter(usersIdsParamList.get(i), usersList.get(i).getUsername()); } List scheduleRequestList = query.getResultList();
Внутренняя строка запроса преобразуется ниже, поэтому я не получаю записи, созданные двумя пользователями, потому что она использует «И».
select generatedAlias0 from ScheduleRequest as generatedAlias0 where ( generatedAlias0.createdBy=:param0 ) and ( generatedAlias0.createdBy=:param1 ) order by generatedAlias0.trackingId asc
- Dapper.Rainbow VS Dapper.Contrib
- Как выполнить неполиморфный запрос HQL в Hibernate?
- Как обновить схемы таблиц базы данных с помощью генерации схемы NHibernate?
- Что такое «собственная сторона» в сопоставлении ORM?
- Вычисленное свойство с JPA / Hibernate
- Объекты ORM и сущности домена в Entity Framework 6.0
- Как использовать hibernate с MS Access?
- Разница между FetchType LAZY и EAGER в Java Persistence API?
Если я хорошо понимаю, вы хотите присоединиться к ScheduleRequest
с User
и применить предложение in
к свойству userName
объекта User
.
Мне нужно немного поработать над этой схемой. Но вы можете попробовать с этим трюком, который гораздо читабельнее, чем код, который вы опубликовали, и избегает части Join
(потому что он обрабатывает логику Join
вне запроса Criteria Query).
List myList = new ArrayList (); for (User u : usersList) { myList.add(u.getUsername()); } Expression exp = scheduleRequest.get("createdBy"); Predicate predicate = exp.in(myList); criteria.where(predicate);
Чтобы написать более безопасный код, вы также можете использовать Metamodel, заменив эту строку:
Expression exp = scheduleRequest.get("createdBy");
с этим:
Expression exp = scheduleRequest.get(ScheduleRequest_.createdBy);
Если это сработает, вы можете попытаться добавить логику Join
в Criteria Query
. Но сейчас я не могу проверить это, поэтому я предпочитаю видеть, хочет ли кто-нибудь еще попробовать.
Не лучший ответ, хотя могут быть fragmentы кода.
public List findListWhereInCondition(Class clazz, String conditionColumnName, Serializable... conditionColumnValues) { QueryBuilder queryBuilder = new QueryBuilder (clazz); addWhereInClause(queryBuilder, conditionColumnName, conditionColumnValues); queryBuilder.select(); return queryBuilder.getResultList(); } private void addWhereInClause(QueryBuilder queryBuilder, String conditionColumnName, Serializable... conditionColumnValues) { Path