Search in sources :

Example 16 with Selection

use of jakarta.persistence.criteria.Selection in project eclipselink by eclipse-ee4j.

the class CriteriaQueryImpl method createCompoundQuery.

/**
 * Translates from the criteria query to a EclipseLink Database Query.
 */
@SuppressWarnings("deprecation")
protected ObjectLevelReadQuery createCompoundQuery() {
    ObjectLevelReadQuery query = null;
    if (this.queryResult == ResultType.UNKNOWN) {
        if (this.selection.isConstructor()) {
            this.queryResult = ResultType.CONSTRUCTOR;
        } else if (this.selection.getJavaType().equals(Tuple.class)) {
            this.queryResult = ResultType.TUPLE;
        } else {
            this.queryResult = ResultType.OBJECT_ARRAY;
        }
    }
    if (this.queryResult.equals(ResultType.PARTIAL)) {
        ReadAllQuery raq = new ReadAllQuery(this.queryType);
        for (Selection selection : this.selection.getCompoundSelectionItems()) {
            raq.addPartialAttribute(((SelectionImpl) selection).currentNode);
        }
        raq.setExpressionBuilder(((InternalSelection) this.selection.getCompoundSelectionItems().get(0)).getCurrentNode().getBuilder());
        query = raq;
    } else {
        ReportQuery reportQuery = null;
        if (this.queryResult.equals(ResultType.CONSTRUCTOR) || this.queryResult.equals(ResultType.OTHER)) {
            // other is also a constructor type if multi-select was called.
            // with a type other than the query type.
            reportQuery = new ReportQuery();
            reportQuery.addConstructorReportItem(((ConstructorSelectionImpl) this.selection).translate());
            reportQuery.setShouldReturnSingleAttribute(true);
        } else {
            if (this.queryResult.equals(ResultType.TUPLE)) {
                reportQuery = new TupleQuery(this.selection == null ? new ArrayList<>() : this.selection.getCompoundSelectionItems());
            } else {
                reportQuery = new ReportQuery();
                reportQuery.setShouldReturnWithoutReportQueryResult(true);
            }
            reportQuery.setExpressionBuilder(((InternalSelection) this.selection.getCompoundSelectionItems().get(0)).getCurrentNode().getBuilder());
            for (Selection nested : this.selection.getCompoundSelectionItems()) {
                if (((SelectionImpl) nested).isConstructor()) {
                    reportQuery.addConstructorReportItem(((ConstructorSelectionImpl) nested).translate());
                } else if (nested.isCompoundSelection()) {
                    throw new IllegalStateException(ExceptionLocalization.buildMessage("NESTED_COMPOUND_SELECTION_OTHER_THAN_CONSTRUCTOR_NOT_SUPPORTED"));
                } else {
                    if (((InternalSelection) nested).isFrom()) {
                        reportQuery.addItem(nested.getAlias(), ((SelectionImpl) nested).getCurrentNode(), ((FromImpl) nested).findJoinFetches());
                    } else if (((InternalExpression) nested).isCompoundExpression() && ((FunctionExpressionImpl) nested).getOperation() == CriteriaBuilderImpl.SIZE) {
                        // selecting size not all databases support subselect in select clause so convert to count/groupby
                        PathImpl collectionExpression = (PathImpl) ((FunctionExpressionImpl) nested).getChildExpressions().get(0);
                        ExpressionImpl fromExpression = (ExpressionImpl) collectionExpression.getParentPath();
                        reportQuery.addAttribute(nested.getAlias(), collectionExpression.getCurrentNode().count(), ClassConstants.INTEGER);
                        reportQuery.addGrouping(fromExpression.getCurrentNode());
                    } else {
                        reportQuery.addAttribute(nested.getAlias(), ((SelectionImpl) nested).getCurrentNode(), nested.getJavaType());
                    }
                }
            }
        }
        ExpressionBuilder builder = null;
        Class<?> queryClazz = null;
        // First check the WHERE clause
        if (this.where != null && ((InternalSelection) this.where).getCurrentNode() != null) {
            builder = ((InternalSelection) this.where).getCurrentNode().getBuilder();
            queryClazz = builder.getQueryClass();
        }
        // Check all the SELECTION items next
        if (queryClazz == null && this.selection != null) {
            for (Selection<?> s : this.selection.getCompoundSelectionItems()) {
                if (((InternalSelection) s).getCurrentNode() != null) {
                    builder = ((InternalSelection) s).getCurrentNode().getBuilder();
                    queryClazz = builder.getQueryClass();
                    if (queryClazz != null) {
                        break;
                    }
                }
            }
        }
        // Fallback on the root
        if (queryClazz == null && this.roots != null) {
            for (Root<?> r : this.roots) {
                if (((RootImpl<?>) r).getCurrentNode() != null) {
                    builder = ((RootImpl<?>) r).getCurrentNode().getBuilder();
                    queryClazz = builder.getQueryClass();
                    if (queryClazz != null) {
                        break;
                    }
                }
            }
        }
        reportQuery.setExpressionBuilder(builder);
        reportQuery.setReferenceClass(queryClazz);
        query = reportQuery;
        if (this.groupBy != null && !this.groupBy.isEmpty()) {
            for (Expression<?> exp : this.groupBy) {
                reportQuery.addGrouping(((InternalSelection) exp).getCurrentNode());
            }
        }
        if (this.havingClause != null) {
            reportQuery.setHavingExpression(((InternalSelection) this.havingClause).getCurrentNode());
        }
    }
    return query;
}
Also used : Selection(jakarta.persistence.criteria.Selection) ReportQuery(org.eclipse.persistence.queries.ReportQuery) ReadAllQuery(org.eclipse.persistence.queries.ReadAllQuery) ExpressionBuilder(org.eclipse.persistence.expressions.ExpressionBuilder) ObjectLevelReadQuery(org.eclipse.persistence.queries.ObjectLevelReadQuery) Tuple(jakarta.persistence.Tuple)

Example 17 with Selection

use of jakarta.persistence.criteria.Selection in project eclipselink by eclipse-ee4j.

the class CriteriaQueryImpl method multiselect.

/**
 * Specify the items that are to be returned in the query result. Replaces
 * the previously specified selection(s), if any.
 *
 * The type of the result of the query execution depends on the
 * specification of the criteria query object as well as the arguments to
 * the multiselect method as follows:
 *
 * If the type of the criteria query is CriteriaQuery&lt;Tuple&gt;, a Tuple object
 * corresponding to the arguments of the multiselect method will be
 * instantiated and returned for each row that results from the query
 * execution.
 *
 * If the type of the criteria query is CriteriaQuery&lt;X&gt; for some
 * user-defined class X, then the arguments to the multiselect method will
 * be passed to the X constructor and an instance of type X will be returned
 * for each row. The IllegalStateException will be thrown if a constructor
 * for the given argument types does not exist.
 *
 * If the type of the criteria query is CriteriaQuery&lt;X[]&gt; for some class X,
 * an instance of type X[] will be returned for each row. The elements of
 * the array will correspond to the arguments of the multiselect method. The
 * IllegalStateException will be thrown if the arguments to the multiselect
 * method are not of type X.
 *
 * If the type of the criteria query is CriteriaQuery&lt;Object&gt;, and only a
 * single argument is passed to the multiselect method, an instance of type
 * Object will be returned for each row.
 *
 * If the type of the criteria query is CriteriaQuery&lt;Object&gt;, and more than
 * one argument is passed to the multiselect method, an instance of type
 * Object[] will be instantiated and returned for each row. The elements of
 * the array will correspond to the arguments to the multiselect method.
 *
 * @param selections
 *            expressions specifying the items that are to be returned in
 *            the query result
 * @return the modified query
 */
@Override
public CriteriaQuery<T> multiselect(Selection<?>... selections) {
    if (selections == null || selections.length == 0) {
        this.selection = null;
        return this;
    }
    for (Selection select : selections) {
        ((SelectionImpl) select).findRootAndParameters(this);
    }
    if (this.queryResult == ResultType.CONSTRUCTOR) {
        populateAndSetConstructorSelection(null, this.queryType, selections);
    } else if (this.queryResult.equals(ResultType.ENTITY)) {
        if (selections.length == 1 && selections[0].getJavaType().equals(this.queryType)) {
            this.selection = (SelectionImpl<?>) selections[0];
        } else {
            try {
                // throws IllegalArgumentException if it doesn't exist
                populateAndSetConstructorSelection(null, this.queryType, selections);
            } catch (IllegalArgumentException constructorDoesNotExist) {
                this.queryResult = ResultType.PARTIAL;
                this.selection = new CompoundSelectionImpl(this.queryType, selections);
            }
        }
    } else if (this.queryResult.equals(ResultType.TUPLE)) {
        this.selection = new CompoundSelectionImpl(this.queryType, selections);
    } else if (this.queryResult.equals(ResultType.OTHER)) {
        if (selections.length == 1 && selections[0].getJavaType().equals(this.queryType)) {
            this.selection = (SelectionImpl<?>) selections[0];
        } else {
            if (!BasicTypeHelperImpl.getInstance().isDateClass(this.queryType)) {
                throw new IllegalArgumentException(ExceptionLocalization.buildMessage("MULTIPLE_SELECTIONS_PASSED_TO_QUERY_WITH_PRIMITIVE_RESULT"));
            }
            populateAndSetConstructorSelection(null, this.queryType, selections);
        }
    } else {
        // unknown
        this.selection = new CompoundSelectionImpl(this.queryType, selections);
    }
    // bug 366386: validate that aliases are not reused
    if (this.selection.isCompoundSelection() && ((CompoundSelectionImpl) this.selection).getDuplicateAliasNames() != null) {
        throw new IllegalArgumentException(ExceptionLocalization.buildMessage("jpa_criteriaapi_alias_reused", new Object[] { ((CompoundSelectionImpl) this.selection).getDuplicateAliasNames() }));
    }
    return this;
}
Also used : Selection(jakarta.persistence.criteria.Selection)

Aggregations

Selection (jakarta.persistence.criteria.Selection)17 CriteriaBuilder (jakarta.persistence.criteria.CriteriaBuilder)11 EntityManager (jakarta.persistence.EntityManager)6 Join (jakarta.persistence.criteria.Join)5 ListJoin (jakarta.persistence.criteria.ListJoin)5 MapJoin (jakarta.persistence.criteria.MapJoin)5 Root (jakarta.persistence.criteria.Root)5 Constructor (java.lang.reflect.Constructor)5 ArrayList (java.util.ArrayList)5 Tuple (jakarta.persistence.Tuple)4 JoinType (jakarta.persistence.criteria.JoinType)4 Order (jakarta.persistence.criteria.Order)4 Path (jakarta.persistence.criteria.Path)4 Iterator (java.util.Iterator)4 List (java.util.List)4 Map (java.util.Map)4 JpaEntityManager (org.eclipse.persistence.jpa.JpaEntityManager)4 Employee (org.eclipse.persistence.testing.models.jpa.advanced.Employee)4 CacheMode (org.hibernate.CacheMode)4 Hibernate (org.hibernate.Hibernate)4