List of usage examples for javax.persistence.criteria CriteriaBuilder and
Predicate and(Expression<Boolean> x, Expression<Boolean> y);
From source file:org.niord.core.message.MessageService.java
/** * Searches out the ID's of the paged result set of messages defined by the search parameters. * Also fills out the total result count of the message search result. * * @param param the search parameters//from w ww. j a v a 2s . c o m * @param result the search result to update with the total result count * @return the paged list of message ID's */ @SuppressWarnings("all") List<Integer> searchPagedMessageIds(MessageSearchParams param, PagedSearchResultVo<Message> result) throws Exception { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<Tuple> tupleQuery = builder.createTupleQuery(); // Select messages Root<Message> msgRoot = tupleQuery.from(Message.class); // Build the predicates based on the search parameters CriteriaHelper<Tuple> criteriaHelper = CriteriaHelper.initWithTupleQuery(em).between(msgRoot.get("updated"), param.getUpdatedFrom(), param.getUpdatedTo()); // Filter by dates if (param.getFrom() != null || param.getTo() != null) { DateType dateType = param.getDateType() != null ? param.getDateType() : DateType.PUBLISH_DATE; Date from = param.getFrom(); Date to = param.getTo(); switch (dateType) { case PUBLISH_DATE: criteriaHelper.overlaps(msgRoot.get("publishDateFrom"), msgRoot.get("publishDateTo"), from, to); break; case EVENT_DATE: criteriaHelper.overlaps(msgRoot.get("eventDateFrom"), msgRoot.get("eventDateTo"), from, to); break; case CREATED_DATE: criteriaHelper.between(msgRoot.get("created"), from, to); break; case UPDATED_DATE: criteriaHelper.between(msgRoot.get("updated"), from, to); break; case PUBLISH_FROM_DATE: criteriaHelper.between(msgRoot.get("publishDateFrom"), from, to); break; case PUBLISH_TO_DATE: criteriaHelper.between(msgRoot.get("publishDateTo"), from, to); break; } } // Main types and sub-types if (!param.getMainTypes().isEmpty()) { criteriaHelper.in(msgRoot.get("mainType"), param.getMainTypes()); } if (!param.getTypes().isEmpty()) { criteriaHelper.in(msgRoot.get("type"), param.getTypes()); } // Statuses if (!param.getStatuses().isEmpty()) { criteriaHelper.in(msgRoot.get("status"), param.getStatuses()); } // Search the Lucene index for free text search if (param.requiresLuceneSearch()) { List<Long> ids = null; try { ids = messageLuceneIndex.searchIndex(param.getQuery(), param.getLanguage(), Integer.MAX_VALUE); } catch (Exception e) { log.warn("Error searching lucene index for query " + param.getQuery()); ids = Collections.emptyList(); } criteriaHelper.in(msgRoot.get("id"), ids); } // Message series if (!param.getSeriesIds().isEmpty()) { criteriaHelper.in(msgRoot.get("messageSeries").get("seriesId"), param.getSeriesIds()); } // Filter by area, join over... if (!param.getAreaIds().isEmpty()) { Join<Message, Area> areas = msgRoot.join("areas", JoinType.LEFT); if (!param.getAreaIds().isEmpty()) { Predicate[] areaMatch = param.getAreaIds().stream().map(aid -> areaService.findByAreaId(aid)) .filter(Objects::nonNull).map(a -> builder.like(areas.get("lineage"), a.getLineage() + "%")) .toArray(Predicate[]::new); criteriaHelper.add(builder.or(areaMatch)); } } // Filter on categories if (!param.getCategoryIds().isEmpty()) { Join<Message, Category> categories = msgRoot.join("categories", JoinType.LEFT); Predicate[] categoryMatch = param.getCategoryIds().stream() .map(cid -> categoryService.findByCategoryId(cid)).filter(Objects::nonNull) .map(c -> builder.like(categories.get("lineage"), c.getLineage() + "%")) .toArray(Predicate[]::new); criteriaHelper.add(builder.or(categoryMatch)); } // Filter on charts if (!param.getChartNumbers().isEmpty()) { Join<Message, Chart> charts = msgRoot.join("charts", JoinType.LEFT); Predicate[] chartMatch = param.getChartNumbers().stream() .map(m -> builder.equal(charts.get("chartNumber"), m)).toArray(Predicate[]::new); criteriaHelper.add(builder.or(chartMatch)); } // Geometry if (param.getExtent() != null) { param.getExtent().setSRID(WGS84_SRID); Join<Message, MessagePart> partRoot = msgRoot.join("parts", JoinType.LEFT); Join<Message, FeatureCollection> fcRoot = partRoot.join("geometry", JoinType.LEFT); Join<FeatureCollection, Feature> fRoot = fcRoot.join("features", JoinType.LEFT); Predicate geomPredicate = new SpatialIntersectsPredicate(criteriaHelper.getCriteriaBuilder(), fRoot.get("geometry"), param.getExtent()); if (param.getIncludeNoPos() != null && param.getIncludeNoPos().booleanValue()) { // search for message with no geometry in addition to messages within extent criteriaHelper.add(builder.or(builder.equal(msgRoot.get("hasGeometry"), false), geomPredicate)); } else { // Only search for messages within extent criteriaHelper.add(geomPredicate); } } // Tags if (!param.getTags().isEmpty()) { Join<Message, MessageTag> tags = msgRoot.join("tags", JoinType.LEFT); String[] tagIds = param.getTags().toArray(new String[param.getTags().size()]); Predicate[] tagMatch = messageTagService.findTags(tagIds).stream() .map(t -> builder.equal(tags.get("id"), t.getId())).toArray(Predicate[]::new); criteriaHelper.add(builder.or(tagMatch)); } // User if (StringUtils.isNotBlank(param.getUsername())) { UserType userType = param.getUserType() == null ? UserType.UPDATED_BY : param.getUserType(); if (userType == UserType.CREATED_BY || userType == UserType.LAST_UPDATED_BY) { String joinCol = userType == UserType.CREATED_BY ? "createdBy" : "lastUpdatedBy"; Join<Message, User> userRoot = msgRoot.join(joinCol, JoinType.LEFT); criteriaHelper.equals(userRoot.get("username"), param.getUsername()); } else { Join<Message, MessageHistory> historyRoot = msgRoot.join("history", JoinType.LEFT); Join<MessageHistory, User> userRoot = historyRoot.join("user", JoinType.LEFT); criteriaHelper.equals(userRoot.get("username"), param.getUsername()); } } // Comments if (param.getCommentsType() != null) { Join<Message, Comment> comments = msgRoot.join("comments", JoinType.LEFT); User user = userService.currentUser(); Predicate own = user != null ? builder.equal(comments.get("user"), user) : null; Predicate exists = builder.isNotNull(comments.get("id")); Predicate unack = builder.isNull(comments.get("acknowledgedBy")); if (user != null && param.getCommentsType() == OWN) { criteriaHelper.add(own); } else if (user != null && param.getCommentsType() == OWN_UNACK) { criteriaHelper.add(builder.and(own, unack)); } else if (param.getCommentsType() == ANY_UNACK) { criteriaHelper.add(builder.and(exists, unack)); } else if (param.getCommentsType() == ANY) { criteriaHelper.add(exists); } } // Refenced messages if (StringUtils.isNotBlank(param.getMessageId())) { int levels = param.getReferenceLevels() == null ? 1 : param.getReferenceLevels(); // NB: This is expensive queries - limit the levels levels = Math.max(0, Math.min(5, levels)); // First, find messages referenced by the message ID Set<Integer> referencedIds = findReferencedMessageIds(new HashSet<>(), param.getMessageId(), levels); // Next, add messages referencing the message ID findReferencingMessageIds(referencedIds, param.getMessageId(), levels); criteriaHelper.in(msgRoot.get("id"), referencedIds); } // Determine the fields to fetch Join<Message, Area> areaRoot = null; Expression<?> treeSortOrder = null; List<Selection<?>> fields = new ArrayList<>(); fields.add(msgRoot.get("id")); if (param.sortByEventDate()) { fields.add(msgRoot.get("eventDateFrom")); fields.add(msgRoot.get("eventDateTo")); } else if (param.sortByPublishDate()) { fields.add(msgRoot.get("publishDateFrom")); fields.add(msgRoot.get("publishDateTo")); } else if (param.sortByFollowUpDate()) { fields.add(msgRoot.get("followUpDate")); } else if (param.sortById()) { fields.add(msgRoot.get("year")); fields.add(msgRoot.get("number")); fields.add(msgRoot.get("publishDateFrom")); } else if (param.sortByArea()) { areaRoot = msgRoot.join("area", JoinType.LEFT); // General messages (without an associated area) should be sorted last treeSortOrder = builder.selectCase().when(builder.isNull(areaRoot.get("treeSortOrder")), 999999) .otherwise(areaRoot.get("treeSortOrder")); fields.add(treeSortOrder); fields.add(msgRoot.get("areaSortOrder")); fields.add(msgRoot.get("year")); fields.add(msgRoot.get("number")); } Selection[] f = fields.toArray(new Selection<?>[fields.size()]); // Complete the query and fetch the message id's (and fields used for sorting) tupleQuery.multiselect(f).distinct(true).where(criteriaHelper.where()); // Sort the query if (param.sortByEventDate()) { if (param.getSortOrder() == SortOrder.ASC) { tupleQuery.orderBy(builder.asc(msgRoot.get("eventDateFrom")), builder.asc(msgRoot.get("eventDateTo")), builder.asc(msgRoot.get("id"))); } else { tupleQuery.orderBy(builder.desc(msgRoot.get("eventDateFrom")), builder.desc(msgRoot.get("eventDateTo")), builder.desc(msgRoot.get("id"))); } } else if (param.sortByPublishDate()) { if (param.getSortOrder() == SortOrder.ASC) { tupleQuery.orderBy(builder.asc(msgRoot.get("publishDateFrom")), builder.asc(msgRoot.get("publishDateTo")), builder.asc(msgRoot.get("id"))); } else { tupleQuery.orderBy(builder.desc(msgRoot.get("publishDateFrom")), builder.desc(msgRoot.get("publishDateTo")), builder.desc(msgRoot.get("id"))); } } else if (param.sortByFollowUpDate()) { if (param.getSortOrder() == SortOrder.ASC) { tupleQuery.orderBy(builder.asc(msgRoot.get("followUpDate")), builder.asc(msgRoot.get("id"))); } else { tupleQuery.orderBy(builder.desc(msgRoot.get("followUpDate")), builder.desc(msgRoot.get("id"))); } } else if (param.sortById()) { if (param.getSortOrder() == SortOrder.ASC) { tupleQuery.orderBy(builder.asc(msgRoot.get("year")), builder.asc(msgRoot.get("number")), builder.asc(msgRoot.get("publishDateFrom")), builder.asc(msgRoot.get("id"))); } else { tupleQuery.orderBy(builder.desc(msgRoot.get("year")), builder.desc(msgRoot.get("number")), builder.desc(msgRoot.get("publishDateFrom")), builder.desc(msgRoot.get("id"))); } } else if (param.sortByArea()) { if (param.getSortOrder() == SortOrder.ASC) { tupleQuery.orderBy(builder.asc(treeSortOrder), builder.asc(msgRoot.get("areaSortOrder")), builder.asc(msgRoot.get("year")), builder.asc(msgRoot.get("number")), builder.asc(msgRoot.get("id"))); } else { tupleQuery.orderBy(builder.desc(treeSortOrder), builder.desc(msgRoot.get("areaSortOrder")), builder.desc(msgRoot.get("year")), builder.desc(msgRoot.get("number")), builder.desc(msgRoot.get("id"))); } } // Execute the query List<Tuple> totalResult = em.createQuery(tupleQuery).getResultList(); // Register the total result result.setTotal(totalResult.size()); List<Integer> msgIds = totalResult.stream().map(t -> (Integer) t.get(0)).collect(Collectors.toList()); // Extract and return the paged sub-list int startIndex = Math.min(msgIds.size(), param.getPage() * param.getMaxSize()); int endIndex = Math.min(msgIds.size(), startIndex + param.getMaxSize()); return msgIds.subList(startIndex, endIndex); }
From source file:org.niord.core.message.MessageTagService.java
/** * Searches for message tags matching the given search parameters * * @param params the search parameters/* w w w. j ava2 s . c o m*/ * @return the search result */ @SuppressWarnings("ResultOfMethodCallIgnored") public List<MessageTag> searchMessageTags(MessageTagSearchParams params) { User user = userService.currentUser(); Domain domain = domainService.currentDomain(); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<MessageTag> query = cb.createQuery(MessageTag.class); Root<MessageTag> tagRoot = query.from(MessageTag.class); // Build the predicate CriteriaHelper<MessageTag> criteriaHelper = new CriteriaHelper<>(cb, query); // Name filtering criteriaHelper.like(tagRoot.get("name"), params.getName()); // Locked filtering criteriaHelper.equals(tagRoot.get("locked"), params.getLocked()); // Type filtering Set<MessageTagType> types = params.getTypes() != null ? params.getTypes() : new HashSet<>(); if (types.isEmpty()) { types.add(PUBLIC); types.add(DOMAIN); types.add(PRIVATE); } List<Predicate> typePredicates = new LinkedList<>(); if (types.contains(PUBLIC)) { typePredicates.add(cb.equal(tagRoot.get("type"), MessageTagType.PUBLIC)); } if (types.contains(DOMAIN) && domain != null) { Join<MessageTag, Domain> domains = tagRoot.join("domain", JoinType.LEFT); typePredicates.add(cb.and(cb.equal(tagRoot.get("type"), MessageTagType.DOMAIN), cb.equal(domains.get("id"), domain.getId()))); } if (types.contains(PRIVATE) && user != null) { Join<MessageTag, User> users = tagRoot.join("user", JoinType.LEFT); typePredicates.add(cb.and(cb.equal(tagRoot.get("type"), MessageTagType.PRIVATE), cb.equal(users.get("id"), user.getId()))); } if (types.contains(TEMP)) { typePredicates.add(cb.equal(tagRoot.get("type"), MessageTagType.TEMP)); } criteriaHelper.add(cb.or(typePredicates.toArray(new Predicate[typePredicates.size()]))); // Compute the sorting List<Order> sortOrders = new ArrayList<>(); Order nameAscSortOrder = cb.asc(cb.lower(tagRoot.get("name"))); if (params.sortByType()) { Expression sortBy = tagRoot.get("type"); sortOrders.add(params.getSortOrder() == DESC ? cb.desc(sortBy) : cb.asc(sortBy)); sortOrders.add(nameAscSortOrder); } else if (params.sortByCreated()) { Expression sortBy = tagRoot.get("created"); sortOrders.add(params.getSortOrder() == DESC ? cb.desc(sortBy) : cb.asc(sortBy)); sortOrders.add(nameAscSortOrder); } else if (params.sortByExpiryDate()) { Expression sortBy = tagRoot.get("expiryDate"); sortOrders.add(params.getSortOrder() == DESC ? cb.desc(sortBy) : cb.asc(sortBy)); sortOrders.add(nameAscSortOrder); } else if (params.sortByMessageCount()) { Expression sortBy = tagRoot.get("messageCount"); sortOrders.add(params.getSortOrder() == DESC ? cb.desc(sortBy) : cb.asc(sortBy)); sortOrders.add(nameAscSortOrder); } else { if (StringUtils.isNotBlank(params.getName())) { sortOrders.add(cb.asc(cb.locate(cb.lower(tagRoot.get("name")), params.getName().toLowerCase()))); } String name = StringUtils.defaultIfBlank(params.getName(), ""); Expression sortBy = cb.lower(tagRoot.get("name")); sortOrders.add(params.getSortOrder() == DESC ? cb.desc(sortBy) : cb.asc(sortBy)); } // Complete the query query.select(tagRoot).distinct(true).where(criteriaHelper.where()).orderBy(sortOrders); // Execute the query and update the search result return em.createQuery(query).setMaxResults(params.getMaxSize()).getResultList(); }
From source file:org.seedstack.i18n.rest.internal.KeyJpaFinder.java
/** * Extracts predicates from criteria./*from www . ja v a2s .c o m*/ * * @param criteria criteria * @param cb criteria builder * @param k root key * @return list of predicate */ private Predicate[] getPredicates(Map<String, Object> criteria, CriteriaQuery q, CriteriaBuilder cb, Root<Key> k) { List<Predicate> predicates = new ArrayList<Predicate>(); if (criteria != null) { // extract criteria from the map Boolean isApprox = (Boolean) criteria.get(IS_APPROX); Boolean isMissing = (Boolean) criteria.get(IS_MISSING); Boolean isOutdated = (Boolean) criteria.get(IS_OUTDATED); String searchName = (String) criteria.get(SEARCH_NAME); // is the key LIKE searchName if (StringUtils.isNotBlank(searchName)) { predicates.add(cb.like(k.<String>get(ENTITY_ID), "%" + searchName + "%")); } // is the key outdated if (isOutdated != null) { predicates.add(cb.equal(k.<Boolean>get(OUTDATED), isOutdated)); } // if a default translation is available String defaultLocale = localeService.getDefaultLocale(); if (defaultLocale != null && isApprox != null) { // join translation table Join<Key, Translation> tln = k.join(TRANSLATIONS, JoinType.LEFT); // WHERE locale = default locale predicates.add(cb.equal(tln.get(ENTITY_ID).get(LOCALE), defaultLocale)); // is the translation approximate predicates.add(cb.equal(tln.get(APPROXIMATE), isApprox)); } // is the translation missing if (isMissing != null) { // SubQuery to find all the key which get a translation for the default locale //noinspection unchecked Subquery<String> subquery = q.subquery(String.class); Root<Key> fromKey = subquery.from(Key.class); subquery.select(fromKey.<String>get(ENTITY_ID)); Join join = fromKey.join(TRANSLATIONS, JoinType.LEFT); subquery.where(cb.and(cb.equal(join.get(ENTITY_ID).get(LOCALE), defaultLocale), cb.notEqual(join.get(VALUE), ""))); // Find all keys not in the above subquery, ie. all the keys missing predicates.add(cb.not(cb.in(k.get(ENTITY_ID)).value(subquery))); } } return predicates.toArray(new Predicate[predicates.size()]); }
From source file:org.seedstack.i18n.rest.internal.TranslationJpaFinder.java
/** * Extracts predicates from criteria./*from w ww . j a v a 2 s. co m*/ * * @param criteria criteria * @param cb criteria builder * @param k root key * @return list of predicate */ private Predicate[] getPredicates(Map<String, Object> criteria, CriteriaQuery q, CriteriaBuilder cb, Root<Key> k) { List<Predicate> predicates = new ArrayList<Predicate>(); if (criteria != null) { // extract criteria from the map Boolean isApprox = (Boolean) criteria.get(IS_APPROX); Boolean isMissing = (Boolean) criteria.get(IS_MISSING); Boolean isOutdated = (Boolean) criteria.get(IS_OUTDATED); String searchName = (String) criteria.get(SEARCH_NAME); String locale = (String) criteria.get(LOCALE); // is the key LIKE searchName if (StringUtils.isNotBlank(searchName)) { predicates.add(cb.like(k.<String>get(ENTITY_ID), "%" + searchName + "%")); } // if a default translation is available if (isApprox != null || isOutdated != null) { // join translation table Join<Key, Translation> tln = k.join(TRANSLATIONS, JoinType.LEFT); // WHERE locale = default locale predicates.add(cb.equal(tln.get(ENTITY_ID).get(LOCALE), locale)); // is the key outdated if (isOutdated != null) { predicates.add(cb.equal(tln.<Boolean>get(OUTDATED), isOutdated)); } // is the translation approximate if (isApprox != null) { predicates.add(cb.equal(tln.<Boolean>get(APPROXIMATE), isApprox)); } } // is the translation missing if (isMissing != null) { // SubQuery to find all the key which get a translation for the default locale //noinspection unchecked Subquery<String> subquery = q.subquery(String.class); Root<Key> fromKey = subquery.from(Key.class); subquery.select(fromKey.<String>get(ENTITY_ID)); Join join = fromKey.join(TRANSLATIONS, JoinType.LEFT); subquery.where(cb.and(cb.equal(join.get(ENTITY_ID).get(LOCALE), locale), cb.notEqual(join.get(VALUE), ""))); // Find all keys not in the above subquery, ie. all the keys missing predicates.add(cb.not(cb.in(k.get(ENTITY_ID)).value(subquery))); } } return predicates.toArray(new Predicate[predicates.size()]); }
From source file:org.sparkcommerce.core.catalog.dao.ProductDaoImpl.java
protected void attachProductSearchCriteria(ProductSearchCriteria searchCriteria, From<?, ? extends Product> product, From<?, ? extends Sku> sku, List<Predicate> restrictions) { CriteriaBuilder builder = em.getCriteriaBuilder(); // Build out the filter criteria from the users request for (Entry<String, String[]> entry : searchCriteria.getFilterCriteria().entrySet()) { String key = entry.getKey(); List<String> eqValues = new ArrayList<String>(); List<String[]> rangeValues = new ArrayList<String[]>(); // Determine which path is the appropriate one to use Path<?> pathToUse;/*www . j a v a 2 s. c o m*/ if (key.contains("defaultSku.")) { pathToUse = sku; key = key.substring("defaultSku.".length()); } else if (key.contains("productAttributes.")) { pathToUse = product.join("productAttributes"); key = key.substring("productAttributes.".length()); restrictions.add(builder.equal(pathToUse.get("name").as(String.class), key)); key = "value"; } else if (key.contains("product.")) { pathToUse = product; key = key.substring("product.".length()); } else { // We don't know which path this facet is built on - resolves previous bug that attempted // to attach search facet to any query parameter continue; } // Values can be equality checks (ie manufacturer=Dave's) or range checks, which take the form // key=range[minRange:maxRange]. Figure out what type of check this is for (String value : entry.getValue()) { if (value.contains("range[")) { String[] rangeValue = new String[] { value.substring(value.indexOf("[") + 1, value.indexOf(":")), value.substring(value.indexOf(":") + 1, value.indexOf("]")) }; rangeValues.add(rangeValue); } else { eqValues.add(value); } } // Add the equality range restriction with the "in" builder. That means that the query string // ?manufacturer=Dave&manufacturer=Bob would match either Dave or Bob if (eqValues.size() > 0) { restrictions.add(pathToUse.get(key).in(eqValues)); } // If we have any range restrictions, we need to build those too. Ranges are also "or"ed together, // such that specifying range[0:5] and range[10:null] for the same field would match items // that were valued between 0 and 5 OR over 10 for that field List<Predicate> rangeRestrictions = new ArrayList<Predicate>(); for (String[] range : rangeValues) { BigDecimal min = new BigDecimal(range[0]); BigDecimal max = null; if (range[1] != null && !range[1].equals("null")) { max = new BigDecimal(range[1]); } Predicate minRange = builder.greaterThan(pathToUse.get(key).as(BigDecimal.class), min); Predicate maxRange = null; if (max != null) { maxRange = builder.lessThan(pathToUse.get(key).as(BigDecimal.class), max); rangeRestrictions.add(builder.and(minRange, maxRange)); } else { rangeRestrictions.add(minRange); } } if (rangeRestrictions.size() > 0) { restrictions.add(builder.or(rangeRestrictions.toArray(new Predicate[rangeRestrictions.size()]))); } } }
From source file:org.xlcloud.service.dao.JpaVirtualClusterDefinitionsDao.java
/** {@inheritDoc} */ @Override//from w w w .j a v a2s . co m public List<VirtualClusterDefinitionModel> findByTypeAndTags(Long accountId, String type, Set<String> tags, boolean paged) { if (LOG.isDebugEnabled()) { LOG.debug("finding vc definitions with type id: " + type + " and following tag ids:" + ToStringBuilder.reflectionToString(tags)); } CriteriaBuilder criteriaBuilder = getCriteriaBuilder(); CriteriaQuery<Tuple> query = criteriaBuilder.createTupleQuery(); Root<VirtualClusterDefinitionModel> vcDefRoot = query.from(VirtualClusterDefinitionModel.class); Predicate typePredicate = criteriaBuilder.equal(vcDefRoot.get(VirtualClusterDefinitionModel_.type), type); Predicate tagsPredicate = vcDefRoot.get(VirtualClusterDefinitionModel_.tags).in(tags); boolean skipTagsJoin = tags.isEmpty(); Predicate predicate = skipTagsJoin ? typePredicate : criteriaBuilder.and(typePredicate, tagsPredicate); Predicate scopePredicate; if (accountId != null) { Predicate accountPredicate = criteriaBuilder .equal(vcDefRoot.get(VirtualClusterDefinitionModel_.accountId), accountId); Predicate privatePredicate = criteriaBuilder .equal(vcDefRoot.get(VirtualClusterDefinitionModel_.catalogScope), CatalogScope.PRIVATE); scopePredicate = criteriaBuilder.and(accountPredicate, privatePredicate); } else { scopePredicate = criteriaBuilder.equal(vcDefRoot.get(VirtualClusterDefinitionModel_.catalogScope), CatalogScope.PUBLIC); } predicate = criteriaBuilder.and(predicate, scopePredicate); query.multiselect(vcDefRoot, criteriaBuilder.count(vcDefRoot)); query.where(predicate); query.groupBy(vcDefRoot); if (!skipTagsJoin) { query.having(criteriaBuilder.equal(criteriaBuilder.count(vcDefRoot), tags.size())); } List<Tuple> list = getResultList(query, vcDefRoot, paged); List<VirtualClusterDefinitionModel> results = new LinkedList<VirtualClusterDefinitionModel>(); for (Tuple t : list) { results.add((VirtualClusterDefinitionModel) t.get(0)); } return results; }