private <S> S aggregate(CriteriaBuilder builder, CriteriaQuery<S> query, Root<E> root, Specification<E> spec, List<Selection<?>> selectionList, LockModeType lockMode) { if (selectionList != null) { Predicate predicate = spec.toPredicate(root, query, builder); if (predicate != null) { query.where(predicate); } query.multiselect(selectionList); return (S) em.createQuery(query).setLockMode(lockMode).getSingleResult(); } return null; }
@Override public T select(Object... selections) { if (!beforeMethodInvoke()) { return (T) this; } List<Selection<?>> list = new ArrayList<Selection<?>>(selections.length); for (Object selection : selections) { if (selection instanceof String) { parseSelectionStr(list, (String) selection); } else if (selection instanceof Selection) { list.add((Selection<?>) selection); } } select(list.toArray(new Selection<?>[list.size()])); return (T) this; }
private void parseSelectionStr(List<Selection<?>> result, String selection) { String[] ps = selection.split("\\s*,\\s*"); for (String p : ps) { String alias = p.trim(); String[] pa = alias.split("\\s+[aA][sS]\\s+"); if (pa.length > 1) { alias = pa[1]; } else { pa = alias.split("\\s+"); if (pa.length > 1) { alias = pa[1]; } } result.add(root.get(ps[0]).alias(alias)); } }
@Override @SuppressWarnings("rawtypes") public T select(Selection<?>... selections) { if (!beforeMethodInvoke()) { return (T) this; } Assert.isTrue(sq == null || selections.length == 1, "selections can only have one in subquery! "); Assert.isTrue(sq == null || selections[0] instanceof Expression, "Elements in the selections must implement the " + Expression.class.getName() + " interface in subquery! "); Assert.isTrue(sq != null || criteria instanceof CriteriaQuery, "Not supported!"); if (sq == null) { ((CriteriaQuery) criteria).multiselect(selections); } else { sq.select((Expression) selections[0]); } for (Selection<?> selection : selections) { aliases.add(selection.getAlias()); } return (T) this; }
/** * @param distinctFields * @return * @throws IllegalArgumentException if the field is not part of the entity */ public JpaELFilterImpl distinct(String... distinctFields) { if (distinctFields != null) { List<Selection> multiSelection = new ArrayList<>(); for (String f : distinctFields) { multiSelection.add(resultRoot.get(f)); } if (distinctFields.length == 1) { critQ.select(multiSelection.get(0)).distinct(true); } else if (distinctFields.length > 0) { critQ.multiselect(multiSelection).distinct(true); } } return this; }
@Override public void addSelection(Expression<?> expression, String name) { Selection<?> selection = criteriaQuery.getSelection(); List<Selection<?>> newSelection = new ArrayList<>(); if (selection != null) { if (selection.isCompoundSelection()) { newSelection.addAll(selection.getCompoundSelectionItems()); } else { newSelection.add(selection); } } newSelection.add(expression); criteriaQuery.multiselect(newSelection); }
/** * {@inheritDoc} */ @Override public <T extends BaseEntity> List<Tuple> findByTupleQuery(TupleQueryCriteria<T> criteria) { EntityManager em = this.emf.createEntityManager(); try { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Tuple> cq = cb.createTupleQuery(); Root<T> root = cq.from(criteria.getEntity()); return em.createQuery(cq.multiselect(criteria.getSelections() .stream() .map(root::get) .collect(Collectors.toList()) .toArray(new Selection[LEN_ZERO])) .where(cb.and(JpaUtil.getPredicates(criteria.getCriteriaAttributes(), cb, root)))) .getResultList(); } catch (RuntimeException ex) { LOGGER.error(ex.getMessage(), ex); throw new PersistenceException(ex.getMessage(), ex); } finally { JpaUtil.closeEntityManager(em); } }
/** * {@inheritDoc} */ @Override public <T extends BaseEntity, C> List<C> findByCriteriaAndMapConstructor(ConstructorCriteria<T, C> criteria) { EntityManager em = this.emf.createEntityManager(); try { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<C> cq = cb.createQuery(criteria.getConstructorClass()); Root<T> root = cq.from(criteria.getEntity()); return em.createQuery(cq.select(cb.construct(criteria.getConstructorClass(), criteria.getSelections() .stream() .map(root::get) .collect(Collectors.toList()) .toArray(new Selection[LEN_ZERO]))) .where(JpaUtil.getPredicates(criteria.getCriteriaAttributes(), cb, root))) .getResultList(); } catch (RuntimeException ex) { LOGGER.error(ex.getMessage(), ex); throw new PersistenceException(ex.getMessage(), ex); } finally { JpaUtil.closeEntityManager(em); } }
/** * {@inheritDoc} */ public boolean visit(JpqlSubselect node, CriteriaHolder query) { try { Subquery<Object> subquery = query.createSubquery(); node.jjtGetChild(1).visit(this, query); node.jjtGetChild(0).visit(this, query); List<Selection<?>> selections = query.<List<Selection<?>>>getCurrentValue(); subquery.select((Expression<Object>)selections.iterator().next()); query.setValue(subquery); for (int i = 2; i < node.jjtGetNumChildren(); i++) { node.jjtGetChild(i).visit(this, query); } query.setValue(subquery); return false; } finally { query.removeSubquery(); } }
@Test public void criteria() { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<ClientEntityBrowserDto> c = cb.createQuery(ClientEntityBrowserDto.class); Root<Client> client = c.from(Client.class); Join<Client, ClientGroup> clientGroup = client.join("group", JoinType.LEFT); Join<Client, ClientStructure> clientStructure = client.join("structure", JoinType.LEFT); Join<ClientType, ClientTypeGroup> clientTypeGroup = client.join("type", JoinType.LEFT).join("clientTypeGroup", JoinType.LEFT); Selection<ClientEntityBrowserDto> selection = cb.construct(ClientEntityBrowserDto.class, client.<Integer>get("id"), client.<String>get("number"), client.<String>get("name"), clientTypeGroup.<String>get("name"), clientGroup.<String>get("name"), clientStructure.<String>get("name")); c.select(selection); c.distinct(true); TypedQuery<ClientEntityBrowserDto> query = entityManager.createQuery(c); assertTrue(query.getResultList().isEmpty()); }
/** * Package-protected method to centralize checking of criteria query multi-selects as defined by the * {@link CriteriaQuery#multiselect(List)} method. * * @param selections The selection varargs to check * * @throws IllegalArgumentException If the selection items are not valid per {@link CriteriaQuery#multiselect} * documentation. * <i>"An argument to the multiselect method must not be a tuple- * or array-valued compound selection item."</i> */ void checkMultiselect(List<Selection<?>> selections) { // final HashSet<String> aliases = new HashSet<String>( CollectionHelper.determineProperSizing( selections.size() ) ); // // for ( Selection<?> selection : selections ) { // if ( selection.isCompoundSelection() ) { // if ( selection.getJavaType().isArray() ) { // throw new IllegalArgumentException( // "Selection items in a multi-select cannot contain compound array-valued elements" // ); // } // if ( Tuple.class.isAssignableFrom( selection.getJavaType() ) ) { // throw new IllegalArgumentException( // "Selection items in a multi-select cannot contain compound tuple-valued elements" // ); // } // } // if ( StringHelper.isNotEmpty( selection.getAlias() ) ) { // boolean added = aliases.add( selection.getAlias() ); // if ( ! added ) { // throw new IllegalArgumentException( "Multi-select expressions defined duplicate alias : " + selection.getAlias() ); // } // } // } }
private List<JpaExpression<?>> toExpressions(List<Selection<?>> selections) { if ( selections == null || selections.isEmpty() ) { return Collections.emptyList(); } final ArrayList<JpaExpression<?>> expressions = new ArrayList<>(); for ( Selection<?> selection : selections ) { if ( selection instanceof JpaExpression ) { expressions.add( (JpaExpression) selection ); } else { throw new CriteriaBuilderException( "Expecting javax.persistence.criteria.Selection to be " + "JpaExpression, but found " + selection.toString() ); } } return expressions; }
public <E> List<Selection<?>> prepareProjectingQuery(MetaJpaConstructor<E,?,?> projection, From<?,? extends E> selection) { logger.debug("prepareProjectingQuery({},{})", projection, selection); List<Selection<?>> ret; if (projection instanceof IdProjection) { logger.debug("IdProjection. Replacing selection {} with just Id.", selection); ret = Collections.<Selection<?>>newList(selection.get(QueryUtils.<E,Object>id(selection.getJavaType(), em.apply()))); } else { ret = newListOfSize(projection.getParameters().size()); for (Tuple3<Integer, Attribute<?,?>, Class<?>> t: zip(range(0), projection.getParameters(), projection.getConstructorParameterTypes())) { int index = t._1; Attribute<?,?> param = t._2; Class<?> constuctorParameterType = t._3; ret.add(transformSelectionForQuery(param, isId(constuctorParameterType) || isWrapperOfIds(projection, index), selection, projection)); } } logger.debug("prepareProjectingQuery -> {}", ret); return ret; }
/** * Create a TypedQuery from a request page * @param page request page * @return new TypedQuery */ @SuppressWarnings("unchecked") private <K> TypedQuery<K> getCriteriaQuery(Page<K> page) { CriteriaQuery<K> criteria = getCriteria(page); CriteriaQuery<Long> countCriteria = (CriteriaQuery<Long>) getCriteria(page); CriteriaBuilder cb = em.getCriteriaBuilder(); Root<?> root = countCriteria.getRoots().iterator().next(); countCriteria.select(cb.count(root)); page.setCount((em.createQuery(countCriteria).getSingleResult()) .intValue()); criteria.orderBy(getOrder(page, criteria)); // Add default select to entity class if none was set. if (criteria.getSelection() == null) { criteria.select((Selection<? extends K>) root); } return em.createQuery(criteria); }
@Override public <S> S aggregate(Class<S> resultClass, Specification<E> spec, AggregateExpression<E> expression, LockModeType lockMode) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<S> query = builder.createQuery(resultClass); Root<E> root = query.from(getDomainClass()); List<Selection<?>> selectionList = expression.buildExpression(root, query, builder); return aggregate(builder, query, root, spec, selectionList, lockMode); }
@Override public <S> S sum(Class<S> resultClass, Specification<E> spec, LockModeType lockMode, List<SingularAttribute<E, ? extends Number>> properties) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<S> query = builder.createQuery(resultClass); Root<E> root = query.from(getDomainClass()); List<Selection<?>> selectionList = Lists.newArrayList(); for (SingularAttribute<E, ? extends Number> property : properties) { selectionList.add(builder.sum(root.get(property))); } return aggregate(builder, query, root, spec, selectionList, lockMode); }
@SuppressWarnings("unchecked") public R sum(String expr) { Expression<Number> path = QueryFormHelper.getExpression(cb, root, expr); query.select((Selection<? extends R>) cb.toDouble(cb.sum(path))); TypedQuery<R> typedQuery = em.createQuery(query); return typedQuery.getSingleResult(); }
@SuppressWarnings({"unchecked", "rawtypes"}) public List<T> buscarTodos(String... atributos) { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery cq = entityManager.getCriteriaBuilder().createQuery(); Root<T> root = cq.from(entityClass); Selection[] selections = new Selection[atributos.length]; for (int i = 0; i < atributos.length; i++) { selections[i] = root.get(atributos[i]); } cq.select(cb.construct(entityClass, selections)); cq.orderBy(cb.desc(root.get("id"))); return entityManager.createQuery(cq).getResultList(); }
@Override public T select(String... selections) { if (!beforeMethodInvoke()) { return (T) this; } List<Selection<?>> list = new ArrayList<Selection<?>>(selections.length); for (String selection : selections) { parseSelectionStr(list, selection); } select(list.toArray(new Selection<?>[list.size()])); return (T) this; }
/** * @param fields * @return * @throws IllegalArgumentException if the field is not part of the entity */ public JpaELFilterImpl selectFields(String[] fields) { List<Selection> multiSelection = new ArrayList<>(); for (String f : fields) { multiSelection.add(resultRoot.get(f)); } critQ.multiselect(multiSelection); return this; }
@Override public <S> S sum(Class<S> resultClass, Specification<E> spec, LockModeType lockMode, List<String> properties) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<S> query = builder.createQuery(resultClass); Root<E> root = query.from(getDomainClass()); List<Selection<?>> selectionList = Lists.newArrayList(); for (String property : properties) { selectionList.add(builder.sum(getAttributeName(root, property))); } return aggregate(builder, query, root, spec, selectionList, lockMode); }
protected List<Selection<?>> getSelections(Root<E> root, CriteriaBuilder builder, String... attributeNames) { List<Selection<?>> columns = Lists.newArrayList(); for(String attributeName : attributeNames) { columns.add(builder.sum(this.getAttributeName(root, attributeName))); } return columns; }
private synchronized String getAlias(Selection<?> selection) { if (selection != null) { String alias = selection.getAlias(); if (alias == null) { if (aliasCount >= 1000) { aliasCount = 0; } alias = "shopGeneratedAlias" + aliasCount++; selection.alias(alias); } return alias; } return null; }
@Override @SuppressWarnings({ "rawtypes" }) public long getTotalRowCount() { Selection<T> selection = query.getSelection(); List<Order> orderList = query.getOrderList(); try { CriteriaBuilder builder = em.getCriteriaBuilder(); Expression<Long> countExpr; Set<Root<?>> roots = query.getRoots(); if (roots.size() != 1) { throw new IllegalStateException("cannot compute totalRowCount in case of multiple query roots"); } if (!query.getGroupList().isEmpty()) { throw new IllegalStateException("cannot compute totalRowCount for grouped queries"); } // transform query to a count query Root root = roots.iterator().next(); countExpr = builder.count(root); query.multiselect(countExpr); query.orderBy(new ArrayList<Order>()); TypedQuery countQuery = em.createQuery(query); return (Long) countQuery.getSingleResult(); } finally { // transform count query back to regular query query.multiselect(selection); query.orderBy(orderList); } }
/** * {@inheritDoc} */ public boolean visit(JpqlSelect node, CriteriaHolder query) { node.jjtGetChild(0).visit(this, query); List<Selection<?>> selections = query.<List<Selection<?>>>getCurrentValue(); if (selections.size() == 1) { query.getCriteria().select((Selection<?>)selections.iterator().next()); } else { query.getCriteria().multiselect(selections); } return visit(node); }
/** * {@inheritDoc} */ public boolean visit(JpqlSelectExpressions node, CriteriaHolder query) { List<Selection<?>> selections = new ArrayList<Selection<?>>(); for (int i = 0; i < node.jjtGetNumChildren(); i++) { node.jjtGetChild(i).visit(this, query); selections.add(query.<Selection<?>>getCurrentValue()); } query.setValue(selections); return false; }
/** * {@inheritDoc} */ public boolean visit(JpqlSelectExpression node, CriteriaHolder query) { validateChildCount(node, 1, 2); node.jjtGetChild(0).visit(this, query); Alias alias = getAlias(node); if (alias != null) { query.<Selection<?>>getCurrentValue().alias(alias.getName()); } return false; }
/** * {@inheritDoc} */ public boolean visit(JpqlConstructor node, CriteriaHolder query) { node.jjtGetChild(0).visit(this, query); String entityName = query.<String>getCurrentValue(); Class<?> entityType = ManagedTypeFilter.forModel(metamodel).filter(entityName.trim()).getJavaType(); List<Selection<?>> constructorParameters = new ArrayList<Selection<?>>(); query.setValue(constructorParameters); for (int i = 1; i < node.jjtGetNumChildren(); i++) { node.jjtGetChild(i).visit(this, query); } Selection<?>[] selection = constructorParameters.toArray(new Selection<?>[constructorParameters.size()]); query.setValue(builder.construct(entityType, selection)); return false; }
/** * {@inheritDoc} */ public boolean visit(JpqlConstructorParameter node, CriteriaHolder query) { List<Selection<?>> selections = query.<List<Selection<?>>>getCurrentValue(); node.jjtGetChild(0).visit(this, query); selections.add(query.<Selection<?>>getCurrentValue()); query.setValue(selections); return false; }
private Path getSelectedPath(int index, Selection<?> selection) { if (selection instanceof Expression) { return getSelectedPath(index, (Expression<?>)selection); } if (selection.getAlias() == null) { selection.alias("alias" + index); } return new Path(selection.getAlias()); }
protected <T> TypedQuery<T> buildCartQuery(String[] names, OrderStatus[] statuses, Date dateCreatedMinThreshold, Boolean isPreview, Class<T> returnType) { CriteriaBuilder builder = em.getCriteriaBuilder(); CriteriaQuery<T> criteria = builder.createQuery(returnType); Root<OrderImpl> root = criteria.from(OrderImpl.class); if (Long.class.equals(returnType)) { criteria.select((Selection<? extends T>) builder.count(root)); } else { criteria.select((Selection<? extends T>) root); } List<Predicate> restrictions = new ArrayList<Predicate>(); List<String> statusList = new ArrayList<String>(); if (statuses != null) { for (OrderStatus status : statuses) { statusList.add(status.getType()); } } else { statusList.add("IN_PROCESS"); } restrictions.add(root.get("status").in(statusList)); if (names != null) { restrictions.add(root.get("name").in(Arrays.asList(names))); } if (dateCreatedMinThreshold != null) { restrictions.add(builder.lessThan(root.get("auditable").get("dateCreated").as(Date.class), dateCreatedMinThreshold)); } if (isPreview != null) { if (isPreview) { restrictions.add(builder.isTrue(root.get("previewable").get("isPreview").as(Boolean.class))); } else { restrictions.add(builder.or(builder.isNull(root.get("previewable").get("isPreview")), builder.isFalse(root.get("previewable").get("isPreview").as(Boolean.class)))); } } criteria.where(restrictions.toArray(new Predicate[restrictions.size()])); return em.createQuery(criteria); }
@Override @SuppressWarnings("unchecked") public CriteriaQuery<T> select(Selection<? extends T> selection) { criteriaBuilder().check( selection ); applySelection( (JpaSelection<? extends T>) selection ); return this; }
@Override @SuppressWarnings({ "unchecked" }) public CriteriaQuery<T> multiselect(List<Selection<?>> selections) { final JpaSelection<? extends T> selection; if ( Tuple.class.isAssignableFrom( getResultType() ) ) { selection = (JpaSelection<? extends T>) criteriaBuilder().tuple( selections ); } else if ( getResultType().isArray() ) { selection = ( JpaSelection<? extends T> ) criteriaBuilder().array( (Class<Object[]>) getResultType(), selections ); } else if ( Object.class.equals( getResultType() ) ) { switch ( selections.size() ) { case 0: { throw new IllegalArgumentException( "empty selections passed to criteria query typed as Object" ); } case 1: { selection = (JpaSelection<? extends T>) selections.get( 0 ); break; } default: { selection = (JpaSelection<? extends T>) criteriaBuilder().array( selections ); } } } else { selection = criteriaBuilder().construct( getResultType(), selections ); } applySelection( selection ); return this; }
public void check(Selection<?> selection) { if ( !JpaSelection.class.isInstance( selection ) ) { throw new CriteriaBuilderException( "Expecting javax.persistence.criteria.Selection to be " + "JpaSelection, but was : " + selection.toString() ); } }
@Override public List<UserModel> findBySetOfUserJids(Collection<String> userJids, long first, long max) { CriteriaBuilder cb = JPA.em().getCriteriaBuilder(); CriteriaQuery<UserModel> query = cb.createQuery(UserModel.class); Root<UserModel> root = query.from(UserModel.class); List<Selection<?>> selection = new ArrayList<>(); selection.add(root.get(UserModel_.id)); selection.add(root.get(UserModel_.username)); selection.add(root.get(UserModel_.name)); selection.add(root.get(UserModel_.profilePictureImageName)); selection.add(root.get(UserModel_.roles)); Predicate condition = root.get(UserModel_.jid).in(userJids); CriteriaBuilder.Case<Long> orderCase = cb.selectCase(); long i = 0; for (String userJid : userJids) { orderCase = orderCase.when(cb.equal(root.get(UserModel_.jid), userJid), i); ++i; } Order order = cb.asc(orderCase.otherwise(i)); query .multiselect(selection) .where(condition) .orderBy(order); List<UserModel> list = JPA.em().createQuery(query).setFirstResult((int) first).setMaxResults((int) max).getResultList(); return list; }
public Query createSelectIDs() { this.generated.distinct(true); generated.orderBy(orders); // Make sure we return the results in the correct order List<Selection<?>> selects = new ArrayList<>(); if (root.getModel().hasSingleIdAttribute()) { selects.add(root.get(root.getModel().getId(root.getModel().getIdType().getJavaType()))); } else throw new NotImplementedException("Cannot handle ID selection with IdClass!"); for (Order order : orders) { selects.add(order.getExpression()); } if (selects.size() == 1) generated.select(selects.get(0)); else generated.multiselect(selects); final Query query = session.createQuery(generated); if (offset != null) query.getQueryOptions().setFirstRow(offset); if (limit != null) query.getQueryOptions().setMaxRows(limit); // Set all the parameters for (Map.Entry<ParameterExpression, Object> entry : this.params.entrySet()) { query.setParameter(entry.getKey(), entry.getValue()); } return query; }