Search in sources :

Example 16 with ObjectExpression

use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.

the class JoinedAttributeManager method prepareJoinExpression.

/**
 * Validate and prepare the join expression.
 */
protected Expression prepareJoinExpression(Expression expression, AbstractSession session) {
    // Must be query key expression.
    if (!expression.isQueryKeyExpression()) {
        throw QueryException.mappingForExpressionDoesNotSupportJoining(expression);
    }
    QueryKeyExpression objectExpression = (QueryKeyExpression) expression;
    // Expression may not have been initialized.
    if (objectExpression.getBuilder().getQueryClass() == null) {
        objectExpression = (QueryKeyExpression) objectExpression.rebuildOn(this.baseExpressionBuilder);
        if (objectExpression.getBuilder().getQueryClass() == null) {
            objectExpression.getBuilder().setQueryClass(this.descriptor.getJavaClass());
        }
    }
    objectExpression.getBuilder().setSession(session.getRootSession(null));
    // Can only join relationships.
    if ((objectExpression.getMapping() == null) || (!objectExpression.getMapping().isJoiningSupported())) {
        throw QueryException.mappingForExpressionDoesNotSupportJoining(objectExpression);
    }
    // Search if any of the expression traverse a 1-m.
    ObjectExpression baseExpression = objectExpression;
    while (!baseExpression.isExpressionBuilder()) {
        // pulled from prepareJoinExpressions
        baseExpression.setShouldUseOuterJoinForMultitableInheritance(true);
        if (((QueryKeyExpression) baseExpression).shouldQueryToManyRelationship()) {
            setIsToManyJoinQuery(true);
        }
        if (baseExpression.shouldUseOuterJoin()) {
            setIsOuterJoinedAttributeQuery(true);
        }
        baseExpression = (ObjectExpression) baseExpression.getBaseExpression();
    }
    return objectExpression;
}
Also used : ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression)

Example 17 with ObjectExpression

use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.

the class JoinedAttributeManager method isMappingInJoinedExpressionList.

/**
 * Iterate through a list of expressions searching for the given attribute name.
 * Return true if it is found, false otherwise.  Only use if the query was preprepared so that join expressions
 * were processed.
 */
protected boolean isMappingInJoinedExpressionList(DatabaseMapping attributeMapping, List joinedExpressionList) {
    for (Iterator joinEnum = joinedExpressionList.iterator(); joinEnum.hasNext(); ) {
        List aggregateMappings = new ArrayList();
        ObjectExpression expression = ((ObjectExpression) joinEnum.next()).getFirstNonAggregateExpressionAfterExpressionBuilder(aggregateMappings);
        if (attributeMapping.isAggregateObjectMapping() && aggregateMappings.contains(attributeMapping)) {
            return true;
        } else if (attributeMapping.equals(expression.getMapping())) {
            // expression may not have been processed yet
            return true;
        }
    }
    return false;
}
Also used : Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression)

Example 18 with ObjectExpression

use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.

the class JoinedAttributeManager method computeNestedQueriesForJoinedExpressions.

/**
 * This method is used when computing the nested queries for joined mappings.
 * It recurses computing the nested mapping queries and their join indexes.
 */
protected void computeNestedQueriesForJoinedExpressions(List joinedExpressions, AbstractSession session, ObjectLevelReadQuery readQuery) {
    for (int index = 0; index < joinedExpressions.size(); index++) {
        ObjectExpression objectExpression = (ObjectExpression) joinedExpressions.get(index);
        // Expression may not have been initialized.
        objectExpression.getBuilder().setSession(session.getRootSession(null));
        if (objectExpression.getBuilder().getQueryClass() == null) {
            objectExpression.getBuilder().setQueryClass(descriptor.getJavaClass());
        }
        // get the first expression after the builder that is not an aggregate, and populate the aggregateMapping list if there are aggregates
        ObjectExpression baseExpression = objectExpression.getFirstNonAggregateExpressionAfterExpressionBuilder(getJoinedAggregateMappings());
        // PERF: Cache local join attribute Expression.
        this.addJoinedAttribute(baseExpression);
        DatabaseMapping mapping = baseExpression.getMapping();
        this.getJoinedAttributeMappings().add(mapping);
        // focus on the base expression.  Nested queries will handle nested expressions, and only need to be processed once
        if (mapping.isForeignReferenceMapping() && !getJoinedMappingQueries_().containsKey(mapping)) {
            // A nested query must be built to pass to the descriptor that looks like the real query execution would.
            ObjectLevelReadQuery nestedQuery = ((ForeignReferenceMapping) mapping).prepareNestedJoins(this, readQuery, session);
            if (nestedQuery != null) {
                // Register the nested query to be used by the mapping for all the objects.
                getJoinedMappingQueries_().put(mapping, nestedQuery);
            }
            if (mapping.isCollectionMapping()) {
                mapping.getContainerPolicy().addNestedJoinsQueriesForMapKey(this, readQuery, session);
            }
        }
    }
}
Also used : ObjectLevelReadQuery(org.eclipse.persistence.queries.ObjectLevelReadQuery) ForeignReferenceMapping(org.eclipse.persistence.mappings.ForeignReferenceMapping) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression)

Example 19 with ObjectExpression

use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.

the class OneToOneMapping method buildObjectJoinExpression.

/**
 * INTERNAL:
 * Used to allow object level comparisons.
 */
@Override
public Expression buildObjectJoinExpression(Expression expression, Object value, AbstractSession session) {
    Expression base = ((ObjectExpression) expression).getBaseExpression();
    Expression foreignKeyJoin = null;
    if (this.mechanism == null) {
        // Allow for equal null.
        if (value == null) {
            if (!isForeignKeyRelationship()) {
                // Need to do a join and compare target foreign key to null.
                for (DatabaseField field : getSourceToTargetKeyFields().values()) {
                    Expression join = null;
                    join = expression.getField(field).equal(null);
                    if (foreignKeyJoin == null) {
                        foreignKeyJoin = join;
                    } else {
                        foreignKeyJoin = foreignKeyJoin.and(join);
                    }
                }
            } else {
                for (DatabaseField field : getSourceToTargetKeyFields().keySet()) {
                    Expression join = null;
                    join = base.getField(field).equal(null);
                    if (foreignKeyJoin == null) {
                        foreignKeyJoin = join;
                    } else {
                        foreignKeyJoin = foreignKeyJoin.and(join);
                    }
                }
            }
        } else {
            if (!getReferenceDescriptor().getJavaClass().isInstance(value)) {
                // Bug 3894351 - ensure any proxys are triggered so we can do a proper class comparison
                value = ProxyIndirectionPolicy.getValueFromProxy(value);
                if (!getReferenceDescriptor().getJavaClass().isInstance(value)) {
                    throw QueryException.incorrectClassForObjectComparison(base, value, this);
                }
            }
            Iterator<Object> keyIterator = Arrays.asList(((CacheId) extractKeyFromReferenceObject(value, session)).getPrimaryKey()).iterator();
            for (DatabaseField field : getSourceToTargetKeyFields().keySet()) {
                Expression join = null;
                join = base.getField(field).equal(keyIterator.next());
                if (foreignKeyJoin == null) {
                    foreignKeyJoin = join;
                } else {
                    foreignKeyJoin = foreignKeyJoin.and(join);
                }
            }
        }
    } else {
        int size = this.mechanism.sourceKeyFields.size();
        Object key = null;
        if (value != null) {
            if (!getReferenceDescriptor().getJavaClass().isInstance(value)) {
                // Bug 3894351 - ensure any proxys are triggered so we can do a proper class comparison
                value = ProxyIndirectionPolicy.getValueFromProxy(value);
                if (!getReferenceDescriptor().getJavaClass().isInstance(value)) {
                    throw QueryException.incorrectClassForObjectComparison(base, value, this);
                }
            }
            key = extractKeyFromReferenceObject(value, session);
            boolean allNulls = true;
            for (int i = 0; i < size; i++) {
                if (((CacheId) key).getPrimaryKey()[i] != null) {
                    allNulls = false;
                    break;
                }
            }
            // the same case
            if (allNulls) {
                value = null;
            }
        }
        if (value != null) {
            for (int i = 0; i < size; i++) {
                DatabaseField field = this.mechanism.sourceKeyFields.get(i);
                Expression join = null;
                join = base.getField(field).equal(((CacheId) key).getPrimaryKey()[i]);
                if (foreignKeyJoin == null) {
                    foreignKeyJoin = join;
                } else {
                    foreignKeyJoin = foreignKeyJoin.and(join);
                }
            }
        } else {
            ReportQuery subQuery = new ReportQuery(this.descriptor.getJavaClass(), new ExpressionBuilder());
            Expression relationTableExp = subQuery.getExpressionBuilder().getTable(this.mechanism.relationTable);
            Expression subSelectExp = null;
            for (int i = 0; i < size; i++) {
                subSelectExp = relationTableExp.getField(this.mechanism.sourceRelationKeyFields.get(i)).equal(base.getField(this.mechanism.sourceKeyFields.get(i))).and(subSelectExp);
            }
            subQuery.setSelectionCriteria(subSelectExp);
            subQuery.dontRetrievePrimaryKeys();
            subQuery.addAttribute("", subQuery.getExpressionBuilder().getField(this.mechanism.sourceKeyFields.get(0)));
            foreignKeyJoin = base.notExists(subQuery);
        }
    }
    return foreignKeyJoin;
}
Also used : FieldExpression(org.eclipse.persistence.internal.expressions.FieldExpression) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) ParameterExpression(org.eclipse.persistence.internal.expressions.ParameterExpression) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) ConstantExpression(org.eclipse.persistence.internal.expressions.ConstantExpression) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression)

Example 20 with ObjectExpression

use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.

the class DatabaseMapping method extractNestedExpressions.

/**
 * INTERNAL:
 * Extract the nested attribute expressions that apply to this mapping.
 * This is used for partial objects, and batch fetching.
 *
 * @param expressions TODO
 * @param newRoot TODO
 * @return TODO
 */
protected List<Expression> extractNestedExpressions(List<Expression> expressions, ExpressionBuilder newRoot) {
    List<Expression> nestedExpressions = new ArrayList<>(expressions.size());
    /*
         * If the expression closest to to the Builder is for this mapping, that expression is rebuilt using
         * newRoot and added to the nestedExpressions list.
         */
    for (Expression next : expressions) {
        // the ForUpdateOfClause.
        if (!next.isQueryKeyExpression()) {
            continue;
        }
        QueryKeyExpression expression = (QueryKeyExpression) next;
        ObjectExpression base = expression;
        boolean afterBase = false;
        while (!base.getBaseExpression().isExpressionBuilder()) {
            base = (ObjectExpression) base.getBaseExpression();
            afterBase = true;
        }
        if (base.getName().equals(getAttributeName())) {
            // Only add the nested expressions for the mapping (not the mapping itself).
            if (afterBase) {
                nestedExpressions.add(expression.rebuildOn(base, newRoot));
            }
        }
    }
    return nestedExpressions;
}
Also used : QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) Expression(org.eclipse.persistence.expressions.Expression) ArrayList(java.util.ArrayList) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression)

Aggregations

ObjectExpression (org.eclipse.persistence.internal.expressions.ObjectExpression)21 Expression (org.eclipse.persistence.expressions.Expression)11 QueryKeyExpression (org.eclipse.persistence.internal.expressions.QueryKeyExpression)10 ArrayList (java.util.ArrayList)7 DatabaseMapping (org.eclipse.persistence.mappings.DatabaseMapping)5 ObjectLevelReadQuery (org.eclipse.persistence.queries.ObjectLevelReadQuery)4 ClassDescriptor (org.eclipse.persistence.descriptors.ClassDescriptor)3 ExpressionBuilder (org.eclipse.persistence.expressions.ExpressionBuilder)3 BaseExpression (org.eclipse.persistence.internal.expressions.BaseExpression)3 ConstantExpression (org.eclipse.persistence.internal.expressions.ConstantExpression)3 FieldExpression (org.eclipse.persistence.internal.expressions.FieldExpression)3 DatabaseTable (org.eclipse.persistence.internal.helper.DatabaseTable)3 ForeignReferenceMapping (org.eclipse.persistence.mappings.ForeignReferenceMapping)3 SingularAttribute (jakarta.persistence.metamodel.SingularAttribute)2 Iterator (java.util.Iterator)2 FunctionExpression (org.eclipse.persistence.internal.expressions.FunctionExpression)2 ParameterExpression (org.eclipse.persistence.internal.expressions.ParameterExpression)2 TableExpression (org.eclipse.persistence.internal.expressions.TableExpression)2 FetchGroup (org.eclipse.persistence.queries.FetchGroup)2 IOException (java.io.IOException)1