下面列出了javax.persistence.criteria.CriteriaQuery#groupBy ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public Map<String, Long> selectTotalScoresByProblemJids(Set<String> problemJids) {
if (problemJids.isEmpty()) {
return Collections.emptyMap();
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<StatsUserProblemModel> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(StatsUserProblemModel_.problemJid),
cb.sum(root.get(StatsUserProblemModel_.score))));
cq.where(
root.get(StatsUserProblemModel_.problemJid).in(problemJids));
cq.groupBy(
root.get(StatsUserProblemModel_.problemJid));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@Override
public Map<String, Long> selectCountsAcceptedByProblemJids(Set<String> problemJids) {
if (problemJids.isEmpty()) {
return Collections.emptyMap();
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<StatsUserProblemModel> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(StatsUserProblemModel_.problemJid),
cb.count(root)));
cq.where(
cb.equal(root.get(StatsUserProblemModel_.verdict), Verdict.ACCEPTED.getCode()),
root.get(StatsUserProblemModel_.problemJid).in(problemJids));
cq.groupBy(
root.get(StatsUserProblemModel_.problemJid));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@Override
public Map<String, Long> selectCountsTriedByProblemJids(Set<String> problemJids) {
if (problemJids.isEmpty()) {
return Collections.emptyMap();
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<StatsUserProblemModel> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(StatsUserProblemModel_.problemJid),
cb.count(root)));
cq.where(
root.get(StatsUserProblemModel_.problemJid).in(problemJids));
cq.groupBy(
root.get(StatsUserProblemModel_.problemJid));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@Override
public Map<String, Long> selectCountsVerdictByUserJid(String userJid) {
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<StatsUserProblemModel> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(StatsUserProblemModel_.verdict),
cb.count(root)));
cq.where(
cb.equal(root.get(StatsUserProblemModel_.userJid), userJid));
cq.groupBy(
root.get(StatsUserProblemModel_.verdict));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@Test
public void callSizeFunction() {
log.info("... callSizeFunction ...");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<Author> root = cq.from(Author.class);
cq.multiselect(root, cb.size(root.get(Author_.books)));
cq.groupBy(root.get(Author_.id));
TypedQuery<Tuple> q = em.createQuery(cq);
List<Tuple> results = q.getResultList();
for (Tuple r : results) {
log.info(r.get(0) + " wrote " + r.get(1) + " books.");
}
em.getTransaction().commit();
em.close();
}
/**
* Return the data count base on the criteria query
*
* @param session : hibernate session
* @param root : entity root which is further used for getting sub filed path from it and set in
* criteria where clause. Ex: Root<ProjectEntity> projectRoot =
* criteriaQuery.from(ProjectEntity.class);
* @param criteria : Hibernate criteria query reference for further process
* @param <T> : T = entity name like ProjectEntity, DatasetEntity, ExperimentEntity etc.
* @return {@link Long} : total records count
*/
public static <T> long count(Session session, Root<T> root, CriteriaQuery<T> criteria) {
final CriteriaBuilder builder = session.getCriteriaBuilder();
final CriteriaQuery<Long> countCriteria = builder.createQuery(Long.class);
countCriteria.select(builder.count(root));
countCriteria.getRoots().addAll(criteria.getRoots());
final Predicate whereRestriction = criteria.getRestriction();
if (whereRestriction != null) {
countCriteria.where(whereRestriction);
}
final Predicate groupRestriction = criteria.getGroupRestriction();
if (groupRestriction != null) {
countCriteria.having(groupRestriction);
}
countCriteria.groupBy(criteria.getGroupList());
countCriteria.distinct(criteria.isDistinct());
return session.createQuery(countCriteria).getSingleResult();
}
public static void applyGroupBy(List<String> groupBys, CriteriaQuery<?> query, Map<String, Expression> selectionMap) {
List<Expression<?>> grouping = new LinkedList<>();
groupBys.stream().forEach(groupBy -> {
Expression<?> filterExpr = selectionMap.get(groupBy);
if (filterExpr == null) {
throw new InvalidArgumentException(String.format("Given filter name [%s] is not existed.", groupBy));
}
grouping.add(filterExpr);
});
query.groupBy(grouping);
}
@Override
public Map<String, Long> selectCountsByProblemSetJids(Set<String> problemSetJids) {
if (problemSetJids.isEmpty()) {
return Collections.emptyMap();
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<ProblemSetProblemModel> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(ProblemSetProblemModel_.problemSetJid),
cb.count(root)));
cq.where(
cb.equal(root.get(ProblemSetProblemModel_.status), "VISIBLE"),
cb.equal(root.get(ProblemSetProblemModel_.type), ProblemType.PROGRAMMING.name()),
root.get(ProblemSetProblemModel_.problemSetJid).in(problemSetJids));
cq.groupBy(
root.get(ProblemSetProblemModel_.problemSetJid));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@Override
public Map<String, Long> selectCountProgrammingByChapterJids(Set<String> chapterJids) {
if (chapterJids.isEmpty()) {
return Collections.emptyMap();
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<ChapterProblemModel> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(ChapterProblemModel_.chapterJid),
cb.count(root)));
cq.where(
cb.equal(root.get(ChapterProblemModel_.status), "VISIBLE"),
cb.equal(root.get(ChapterProblemModel_.type), ProblemType.PROGRAMMING.name()),
root.get(ChapterProblemModel_.chapterJid).in(chapterJids));
cq.groupBy(
root.get(ChapterProblemModel_.chapterJid));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@Override
public Map<String, Long> selectCounts(String containerJid, String userJid, Set<String> problemJids) {
if (problemJids.isEmpty()) {
return Collections.emptyMap();
}
CriteriaBuilder cb = currentSession().getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<M> root = cq.from(getEntityClass());
cq.select(cb.tuple(
root.get(AbstractProgrammingSubmissionModel_.problemJid),
cb.count(root)));
cq.where(
cb.equal(root.get(AbstractProgrammingSubmissionModel_.containerJid), containerJid),
cb.equal(root.get(JudgelsModel_.createdBy), userJid),
root.get(AbstractProgrammingSubmissionModel_.problemJid).in(problemJids));
cq.groupBy(
root.get(AbstractProgrammingSubmissionModel_.containerJid),
root.get(JudgelsModel_.createdBy),
root.get(AbstractProgrammingSubmissionModel_.problemJid));
return currentSession().createQuery(cq).getResultList()
.stream()
.collect(Collectors.toMap(tuple -> tuple.get(0, String.class), tuple -> tuple.get(1, Long.class)));
}
@SuppressWarnings("unchecked")
public static <T> TypedQuery<Long> getCountQuery(CriteriaQuery<T> cq) {
Class<T> domainClass = cq.getResultType();
EntityManager em = getEntityManager(domainClass);
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> countCq = cb.createQuery(Long.class);
Root<T> root;
if (cq.getRestriction() != null) {
countCq.where(cq.getRestriction());
}
if (cq.getGroupRestriction() != null) {
countCq.having(cq.getGroupRestriction());
}
if (cq.getRoots().isEmpty()) {
root = countCq.from(domainClass);
} else {
countCq.getRoots().addAll(cq.getRoots());
root = (Root<T>) countCq.getRoots().iterator().next();
}
countCq.groupBy(cq.getGroupList());
if (cq.isDistinct()) {
countCq.select(cb.countDistinct(root));
} else {
countCq.select(cb.count(root));
}
return em.createQuery(countCq);
}
public List<Object[]> findCountByCategoryUsingCriteriaBuilder() {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Object[]> query = builder.createQuery(Object[].class);
Root<Product> product = query.from(Product.class);
query.multiselect(product.get("category"), builder.count(product));
query.groupBy(product.get("category"));
List<Object[]> resultList = entityManager.createQuery(query).getResultList();
return resultList;
}
/**
* Get a predicate using the specified parameters.
*
* @param root The {@link Root} (from) for this query
* @param cq The {@link CriteriaQuery} instance this predicate is for
* @param cb The {@link CriteriaBuilder} for the query
* @param name The name of the command
* @param user The name of the user who created the command
* @param statuses The status of the command
* @param tags The set of tags to search the command for
* @return A {@link Predicate} object used for querying
*/
public static Predicate find(
final Root<CommandEntity> root,
final CriteriaQuery<?> cq,
final CriteriaBuilder cb,
@Nullable final String name,
@Nullable final String user,
@Nullable final Set<String> statuses,
@Nullable final Set<TagEntity> tags
) {
final List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(name)) {
predicates.add(
PredicateUtils.getStringLikeOrEqualPredicate(cb, root.get(CommandEntity_.name), name)
);
}
if (StringUtils.isNotBlank(user)) {
predicates.add(
PredicateUtils.getStringLikeOrEqualPredicate(cb, root.get(CommandEntity_.user), user)
);
}
if (statuses != null && !statuses.isEmpty()) {
predicates.add(
cb.or(
statuses
.stream()
.map(status -> cb.equal(root.get(CommandEntity_.status), status))
.toArray(Predicate[]::new)
)
);
}
if (tags != null && !tags.isEmpty()) {
final Join<CommandEntity, TagEntity> tagEntityJoin = root.join(CommandEntity_.tags);
predicates.add(tagEntityJoin.in(tags));
cq.groupBy(root.get(CommandEntity_.id));
cq.having(cb.equal(cb.count(root.get(CommandEntity_.id)), tags.size()));
}
return cb.and(predicates.toArray(new Predicate[0]));
}
/**
* Copy criteria without selection and order.
* @param from source Criteria.
* @param to destination Criteria.
*/
private static void copyCriteriaWithoutSelectionAndOrder(
CriteriaQuery<?> from, CriteriaQuery<?> to, boolean copyFetches) {
if (isEclipseLink(from) && from.getRestriction() != null) {
// EclipseLink adds roots from predicate paths to critera. Skip copying
// roots as workaround.
}
else {
// Copy Roots
for (Root<?> root : from.getRoots()) {
Root<?> dest = to.from(root.getJavaType());
dest.alias(getOrCreateAlias(root));
copyJoins(root, dest);
if (copyFetches)
copyFetches(root, dest);
}
}
to.groupBy(from.getGroupList());
to.distinct(from.isDistinct());
if (from.getGroupRestriction() != null)
to.having(from.getGroupRestriction());
Predicate predicate = from.getRestriction();
if (predicate != null)
to.where(predicate);
}
@Override
public Integer getBusinessObjectDataLimitedCountBySearchKey(BusinessObjectDataSearchKey businessObjectDataSearchKey, Integer recordCountLimit)
{
// Create the criteria builder and the criteria.
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<String> criteria = builder.createQuery(String.class);
// The criteria root is the business object data.
Root<BusinessObjectDataEntity> businessObjectDataEntityRoot = criteria.from(BusinessObjectDataEntity.class);
// Namespace and business object definition are required parameters, so fetch the relative business object definition entity to optimize the main query.
BusinessObjectDefinitionEntity businessObjectDefinitionEntity = businessObjectDefinitionDao.getBusinessObjectDefinitionByKey(
new BusinessObjectDefinitionKey(businessObjectDataSearchKey.getNamespace(), businessObjectDataSearchKey.getBusinessObjectDefinitionName()));
// If specified business object definition does not exist, then return a zero record count.
if (businessObjectDefinitionEntity == null)
{
return 0;
}
// If file type is specified, fetch the relative entity to optimize the main query.
FileTypeEntity fileTypeEntity = null;
if (StringUtils.isNotBlank(businessObjectDataSearchKey.getBusinessObjectFormatFileType()))
{
fileTypeEntity = fileTypeDao.getFileTypeByCode(businessObjectDataSearchKey.getBusinessObjectFormatFileType());
// If specified file type does not exist, then return a zero record count.
if (fileTypeEntity == null)
{
return 0;
}
}
// Join to the other tables we can filter on.
Join<BusinessObjectDataEntity, BusinessObjectFormatEntity> businessObjectFormatEntityJoin =
businessObjectDataEntityRoot.join(BusinessObjectDataEntity_.businessObjectFormat);
// Add select clause to the query. We use business object data partition value column for select, since this is enough to check the record count.
criteria.select(businessObjectDataEntityRoot.get(BusinessObjectDataEntity_.partitionValue));
// Add standard restrictions to the query. (i.e. the standard where clauses).
try
{
criteria.where(getQueryPredicateBySearchKey(builder, businessObjectDataEntityRoot, businessObjectFormatEntityJoin, businessObjectDataSearchKey,
businessObjectDefinitionEntity, fileTypeEntity));
}
catch (IllegalArgumentException ex)
{
// This exception means that there are no records found for the query, thus return 0 record count.
return 0;
}
// If latest valid version filter is specified, ignore business object format and business object data versions when counting search results.
// In order to do that, we group by all elements of business object data alternate key, except for the versions. Please note that we need to apply
// upper() call on business object format usage, since it is not a dictionary value (does not have the relative lookup table).
if (BooleanUtils.isTrue(businessObjectDataSearchKey.isFilterOnLatestValidVersion()))
{
List<Expression<?>> groupBy = new ArrayList<>();
groupBy.add(businessObjectFormatEntityJoin.get(BusinessObjectFormatEntity_.businessObjectDefinitionId));
groupBy.add(builder.upper(businessObjectFormatEntityJoin.get(BusinessObjectFormatEntity_.usage)));
groupBy.add(businessObjectFormatEntityJoin.get(BusinessObjectFormatEntity_.fileTypeCode));
groupBy.add(businessObjectDataEntityRoot.get(BusinessObjectDataEntity_.partitionValue));
groupBy.add(businessObjectDataEntityRoot.get(BusinessObjectDataEntity_.partitionValue2));
groupBy.add(businessObjectDataEntityRoot.get(BusinessObjectDataEntity_.partitionValue3));
groupBy.add(businessObjectDataEntityRoot.get(BusinessObjectDataEntity_.partitionValue4));
groupBy.add(businessObjectDataEntityRoot.get(BusinessObjectDataEntity_.partitionValue5));
criteria.groupBy(groupBy);
}
// Execute the query.
List<String> businessObjectDataPartitionValues = entityManager.createQuery(criteria).setMaxResults(recordCountLimit).getResultList();
// Return the size of the result list.
return CollectionUtils.size(businessObjectDataPartitionValues);
}
@Override
public List<BusinessObjectFormatKey> getBusinessObjectFormatsWithFilters(BusinessObjectDefinitionKey businessObjectDefinitionKey,
String businessObjectFormatUsage, boolean latestBusinessObjectFormatVersion)
{
// Create the criteria builder and a tuple style criteria query.
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> criteria = builder.createTupleQuery();
// The criteria root is the business object format.
Root<BusinessObjectFormatEntity> businessObjectFormatEntity = criteria.from(BusinessObjectFormatEntity.class);
// Join to the other tables we can filter on.
Join<BusinessObjectFormatEntity, BusinessObjectDefinitionEntity> businessObjectDefinitionEntity =
businessObjectFormatEntity.join(BusinessObjectFormatEntity_.businessObjectDefinition);
Join<BusinessObjectFormatEntity, FileTypeEntity> fileTypeEntity = businessObjectFormatEntity.join(BusinessObjectFormatEntity_.fileType);
Join<BusinessObjectDefinitionEntity, NamespaceEntity> namespaceEntity = businessObjectDefinitionEntity.join(BusinessObjectDefinitionEntity_.namespace);
// Get the columns.
Path<String> namespaceCodeColumn = namespaceEntity.get(NamespaceEntity_.code);
Path<String> businessObjectDefinitionNameColumn = businessObjectDefinitionEntity.get(BusinessObjectDefinitionEntity_.name);
Path<String> businessObjectFormatUsageColumn = businessObjectFormatEntity.get(BusinessObjectFormatEntity_.usage);
Path<String> fileTypeCodeColumn = fileTypeEntity.get(FileTypeEntity_.code);
Path<Integer> businessObjectFormatVersionColumn = businessObjectFormatEntity.get(BusinessObjectFormatEntity_.businessObjectFormatVersion);
Expression<Integer> maxBusinessObjectFormatVersionExpression =
builder.max(businessObjectFormatEntity.get(BusinessObjectFormatEntity_.businessObjectFormatVersion));
// Create the standard restrictions (i.e. the standard where clauses).
Predicate queryRestriction =
builder.equal(builder.upper(namespaceEntity.get(NamespaceEntity_.code)), businessObjectDefinitionKey.getNamespace().toUpperCase());
queryRestriction = builder.and(queryRestriction, builder.equal(builder.upper(businessObjectDefinitionEntity.get(BusinessObjectDefinitionEntity_.name)),
businessObjectDefinitionKey.getBusinessObjectDefinitionName().toUpperCase()));
// Add the business object format usage where parameter is not empty
if (StringUtils.isNotEmpty(businessObjectFormatUsage))
{
queryRestriction = builder.and(queryRestriction,
builder.equal(builder.upper(businessObjectFormatEntity.get(BusinessObjectFormatEntity_.usage)), businessObjectFormatUsage.toUpperCase()));
}
// Add the select clause.
criteria.multiselect(namespaceCodeColumn, businessObjectDefinitionNameColumn, businessObjectFormatUsageColumn, fileTypeCodeColumn,
latestBusinessObjectFormatVersion ? maxBusinessObjectFormatVersionExpression : businessObjectFormatVersionColumn);
// Add the where clause.
criteria.where(queryRestriction);
// If only the latest (maximum) business object format versions to be returned, create and apply the group by clause.
if (latestBusinessObjectFormatVersion)
{
List<Expression<?>> grouping = new ArrayList<>();
grouping.add(namespaceCodeColumn);
grouping.add(businessObjectDefinitionNameColumn);
grouping.add(businessObjectFormatUsageColumn);
grouping.add(fileTypeCodeColumn);
criteria.groupBy(grouping);
}
// Add the order by clause.
List<Order> orderBy = new ArrayList<>();
orderBy.add(builder.asc(businessObjectFormatUsageColumn));
orderBy.add(builder.asc(fileTypeCodeColumn));
if (!latestBusinessObjectFormatVersion)
{
orderBy.add(builder.asc(businessObjectFormatVersionColumn));
}
criteria.orderBy(orderBy);
// Run the query to get a list of tuples back.
List<Tuple> tuples = entityManager.createQuery(criteria).getResultList();
// Populate the "keys" objects from the returned tuples (i.e. 1 tuple for each row).
List<BusinessObjectFormatKey> businessObjectFormatKeys = new ArrayList<>();
for (Tuple tuple : tuples)
{
BusinessObjectFormatKey businessObjectFormatKey = new BusinessObjectFormatKey();
businessObjectFormatKeys.add(businessObjectFormatKey);
businessObjectFormatKey.setNamespace(tuple.get(namespaceCodeColumn));
businessObjectFormatKey.setBusinessObjectDefinitionName(tuple.get(businessObjectDefinitionNameColumn));
businessObjectFormatKey.setBusinessObjectFormatUsage(tuple.get(businessObjectFormatUsageColumn));
businessObjectFormatKey.setBusinessObjectFormatFileType(tuple.get(fileTypeCodeColumn));
businessObjectFormatKey.setBusinessObjectFormatVersion(
tuple.get(latestBusinessObjectFormatVersion ? maxBusinessObjectFormatVersionExpression : businessObjectFormatVersionColumn));
}
return businessObjectFormatKeys;
}
/**
* Get a {@link Predicate} using the specified parameters.
*
* @param root The {@link Root} (from) for this query
* @param cq The {@link CriteriaQuery} instance this predicate is for
* @param cb The {@link CriteriaBuilder} for the query
* @param name The name of the application
* @param user The name of the user who created the application
* @param statuses The status of the application
* @param tags The set of tags to search with
* @param type The type of applications to fine
* @return A specification object used for querying
*/
public static Predicate find(
final Root<ApplicationEntity> root,
final CriteriaQuery<?> cq,
final CriteriaBuilder cb,
@Nullable final String name,
@Nullable final String user,
@Nullable final Set<String> statuses,
@Nullable final Set<TagEntity> tags,
@Nullable final String type
) {
final List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(name)) {
predicates.add(
PredicateUtils.getStringLikeOrEqualPredicate(cb, root.get(ApplicationEntity_.name), name)
);
}
if (StringUtils.isNotBlank(user)) {
predicates.add(
PredicateUtils.getStringLikeOrEqualPredicate(cb, root.get(ApplicationEntity_.user), user)
);
}
if (statuses != null && !statuses.isEmpty()) {
predicates.add(
cb.or(
statuses
.stream()
.map(status -> cb.equal(root.get(ApplicationEntity_.status), status))
.toArray(Predicate[]::new)
)
);
}
if (tags != null && !tags.isEmpty()) {
final Join<ApplicationEntity, TagEntity> tagEntityJoin = root.join(ApplicationEntity_.tags);
predicates.add(tagEntityJoin.in(tags));
cq.groupBy(root.get(ApplicationEntity_.id));
cq.having(cb.equal(cb.count(root.get(ApplicationEntity_.id)), tags.size()));
}
if (StringUtils.isNotBlank(type)) {
predicates.add(
PredicateUtils.getStringLikeOrEqualPredicate(cb, root.get(ApplicationEntity_.type), type)
);
}
return cb.and(predicates.toArray(new Predicate[0]));
}
/**
* Generate a {@link Predicate} given the parameters.
*
* @param root The {@link Root} of the query
* @param cq The {@link CriteriaQuery}
* @param cb The {@link CriteriaBuilder}
* @param name The name of the cluster to find
* @param statuses The statuses of the clusters to find
* @param tags The tags of the clusters to find
* @param minUpdateTime The minimum updated time of the clusters to find
* @param maxUpdateTime The maximum updated time of the clusters to find
* @return The {@link Predicate} representing these parameters
*/
public static Predicate find(
final Root<ClusterEntity> root,
final CriteriaQuery<?> cq,
final CriteriaBuilder cb,
@Nullable final String name,
@Nullable final Set<String> statuses,
@Nullable final Set<TagEntity> tags,
@Nullable final Instant minUpdateTime,
@Nullable final Instant maxUpdateTime
) {
final List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(name)) {
predicates.add(
PredicateUtils.getStringLikeOrEqualPredicate(cb, root.get(ClusterEntity_.name), name)
);
}
if (minUpdateTime != null) {
predicates.add(cb.greaterThanOrEqualTo(root.get(ClusterEntity_.updated), minUpdateTime));
}
if (maxUpdateTime != null) {
predicates.add(cb.lessThan(root.get(ClusterEntity_.updated), maxUpdateTime));
}
if (tags != null && !tags.isEmpty()) {
final Join<ClusterEntity, TagEntity> tagEntityJoin = root.join(ClusterEntity_.tags);
predicates.add(tagEntityJoin.in(tags));
cq.groupBy(root.get(ClusterEntity_.id));
cq.having(cb.equal(cb.count(root.get(ClusterEntity_.id)), tags.size()));
}
if (statuses != null && !statuses.isEmpty()) {
//Could optimize this as we know size could use native array
predicates.add(
cb.or(
statuses
.stream()
.map(status -> cb.equal(root.get(ClusterEntity_.status), status))
.toArray(Predicate[]::new)
)
);
}
return cb.and(predicates.toArray(new Predicate[0]));
}