Search in sources :

Example 6 with ObjectExpression

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

the class ObjectBuilder method loadJoinedAttributes.

protected void loadJoinedAttributes(ClassDescriptor concreteDescriptor, Object sourceObject, CacheKey cacheKey, AbstractRecord databaseRow, JoinedAttributeManager joinManager, ObjectBuildingQuery query, boolean isTargetProtected) {
    boolean useOnlyMappingsExcludedFromSOP = false;
    if (concreteDescriptor.hasSerializedObjectPolicy() && query.shouldUseSerializedObjectPolicy()) {
        // sopObject has not been deserialized, sourceObject must be cached
        useOnlyMappingsExcludedFromSOP = databaseRow.get(concreteDescriptor.getSerializedObjectPolicy().getField()) != null;
    }
    Boolean isUntriggeredResultSetRecord = null;
    List<Expression> joinExpressions = joinManager.getJoinedAttributeExpressions();
    int size = joinExpressions.size();
    for (int index = 0; index < size; index++) {
        QueryKeyExpression queryKeyExpression = (QueryKeyExpression) joinExpressions.get(index);
        QueryKeyExpression baseExpression = (QueryKeyExpression) joinManager.getJoinedAttributes().get(index);
        DatabaseMapping mapping = joinManager.getJoinedAttributeMappings().get(index);
        // Only worry about immediate (excluding aggregates) foreign reference mapping attributes.
        if (queryKeyExpression == baseExpression) {
            if (mapping == null) {
                throw ValidationException.missingMappingForAttribute(concreteDescriptor, queryKeyExpression.getName(), toString());
            } else {
                if (!useOnlyMappingsExcludedFromSOP || mapping.isOutSopObject()) {
                    // get the intermediate objects between this expression node and the base builder
                    Object intermediateValue = joinManager.getValueFromObjectForExpression(query.getExecutionSession(), sourceObject, (ObjectExpression) baseExpression.getBaseExpression());
                    // Bug 4230655 - do not replace instantiated valueholders.
                    Object attributeValue = mapping.getAttributeValueFromObject(intermediateValue);
                    if ((attributeValue != null) && mapping.isForeignReferenceMapping() && ((ForeignReferenceMapping) mapping).usesIndirection() && (!((ForeignReferenceMapping) mapping).getIndirectionPolicy().objectIsInstantiated(attributeValue))) {
                        if (mapping.isObjectReferenceMapping() && ((ObjectReferenceMapping) mapping).isForeignKeyRelationship() && !mapping.isPrimaryKeyMapping()) {
                            if (isUntriggeredResultSetRecord == null) {
                                isUntriggeredResultSetRecord = databaseRow instanceof ResultSetRecord && ((ResultSetRecord) databaseRow).hasResultSet();
                            }
                            if (isUntriggeredResultSetRecord) {
                                for (DatabaseField field : mapping.getFields()) {
                                    // extract the values from ResultSet into the row
                                    databaseRow.get(field);
                                }
                            }
                        }
                        AbstractSession session = query.getExecutionSession();
                        mapping.readFromRowIntoObject(databaseRow, joinManager, intermediateValue, cacheKey, query, query.getExecutionSession(), isTargetProtected);
                        session.getIdentityMapAccessorInstance().getIdentityMap(concreteDescriptor).lazyRelationshipLoaded(intermediateValue, (ValueHolderInterface) ((ForeignReferenceMapping) mapping).getIndirectionPolicy().getOriginalValueHolder(attributeValue, session), (ForeignReferenceMapping) mapping);
                    }
                }
            }
        }
    }
}
Also used : ObjectReferenceMapping(org.eclipse.persistence.mappings.ObjectReferenceMapping) DatabaseMapping(org.eclipse.persistence.mappings.DatabaseMapping) SimpleResultSetRecord(org.eclipse.persistence.internal.sessions.SimpleResultSetRecord) ResultSetRecord(org.eclipse.persistence.internal.sessions.ResultSetRecord) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) ForeignReferenceMapping(org.eclipse.persistence.mappings.ForeignReferenceMapping) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) Expression(org.eclipse.persistence.expressions.Expression) DatabaseField(org.eclipse.persistence.internal.helper.DatabaseField) InvalidObject(org.eclipse.persistence.internal.helper.InvalidObject) AbstractSession(org.eclipse.persistence.internal.sessions.AbstractSession)

Example 7 with ObjectExpression

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

the class ForeignReferenceMapping method prepareNestedBatchQuery.

/**
 * INTERNAL:
 * Clone and prepare the selection query as a nested batch read query.
 * This is used for nested batch reading.
 */
public ReadQuery prepareNestedBatchQuery(ObjectLevelReadQuery query) {
    // For CR#2646-S.M.  In case of inheritance the descriptor to use may not be that
    // of the source query (the base class descriptor), but that of the subclass, if the
    // attribute is only of the subclass.  Thus in this case use the descriptor from the mapping.
    // Also: for Bug 5478648 - Do not switch the descriptor if the query's descriptor is an aggregate
    ClassDescriptor descriptorToUse = query.getDescriptor();
    if ((descriptorToUse != this.descriptor) && (!descriptorToUse.getMappings().contains(this)) && (!this.descriptor.isDescriptorTypeAggregate())) {
        descriptorToUse = this.descriptor;
    }
    ExpressionBuilder builder = new ExpressionBuilder(this.referenceClass);
    builder.setQueryClassAndDescriptor(this.referenceClass, getReferenceDescriptor());
    ReadAllQuery batchQuery = new ReadAllQuery(this.referenceClass, builder);
    batchQuery.setName(getAttributeName());
    batchQuery.setDescriptor(getReferenceDescriptor());
    batchQuery.setSession(query.getSession());
    batchQuery.setShouldUseSerializedObjectPolicy(query.shouldUseSerializedObjectPolicy());
    // bug 3965568
    // we should not wrap the results as this is an internal query
    batchQuery.setShouldUseWrapperPolicy(false);
    if (query.shouldCascadeAllParts() || (query.shouldCascadePrivateParts() && isPrivateOwned()) || (query.shouldCascadeByMapping() && this.cascadeRefresh)) {
        batchQuery.setShouldRefreshIdentityMapResult(query.shouldRefreshIdentityMapResult());
        batchQuery.setCascadePolicy(query.getCascadePolicy());
        batchQuery.setShouldMaintainCache(query.shouldMaintainCache());
        if (query.hasAsOfClause()) {
            batchQuery.setAsOfClause(query.getAsOfClause());
        }
        // bug 3802197 - cascade binding and prepare settings
        batchQuery.setShouldBindAllParameters(query.getShouldBindAllParameters());
        batchQuery.setShouldPrepare(query.shouldPrepare());
    }
    batchQuery.setShouldOuterJoinSubclasses(query.shouldOuterJoinSubclasses());
    // CR #4365
    batchQuery.setQueryId(query.getQueryId());
    Expression batchSelectionCriteria = null;
    // Build the batch query, either using joining, or an exist sub-select.
    BatchFetchType batchType = query.getBatchFetchPolicy().getType();
    if (this.batchFetchType != null) {
        batchType = this.batchFetchType;
    }
    if (batchType == BatchFetchType.EXISTS) {
        // Using a EXISTS sub-select (WHERE EXIST (<original-query> AND <mapping-join> AND <mapping-join>)
        ExpressionBuilder subBuilder = new ExpressionBuilder(descriptorToUse.getJavaClass());
        subBuilder.setQueryClassAndDescriptor(descriptorToUse.getJavaClass(), descriptorToUse);
        ReportQuery subQuery = new ReportQuery(descriptorToUse.getJavaClass(), subBuilder);
        subQuery.setDescriptor(descriptorToUse);
        subQuery.setShouldRetrieveFirstPrimaryKey(true);
        Expression subCriteria = subBuilder.twist(getSelectionCriteria(), builder);
        if (query.getSelectionCriteria() != null) {
            // For bug 2612567, any query can have batch attributes, so the
            // original selection criteria can be quite complex, with multiple
            // builders (i.e. for parallel selects).
            // Now uses cloneUsing(newBase) instead of rebuildOn(newBase).
            subCriteria = query.getSelectionCriteria().cloneUsing(subBuilder).and(subCriteria);
        }
        // Check for history and set asOf.
        if (descriptorToUse.getHistoryPolicy() != null) {
            if (query.getSession().getAsOfClause() != null) {
                subBuilder.asOf(query.getSession().getAsOfClause());
            } else if (batchQuery.getAsOfClause() == null) {
                subBuilder.asOf(AsOfClause.NO_CLAUSE);
            } else {
                subBuilder.asOf(batchQuery.getAsOfClause());
            }
        }
        subQuery.setSelectionCriteria(subCriteria);
        batchSelectionCriteria = builder.exists(subQuery);
    } else if (batchType == BatchFetchType.IN) {
        // Using a IN with foreign key values (WHERE FK IN :QUERY_BATCH_PARAMETER)
        batchSelectionCriteria = buildBatchCriteria(builder, query);
    } else {
        // Using a join, (WHERE <orginal-query-criteria> AND <mapping-join>)
        // Join the query where clause with the mapping's,
        // this will cause a join that should bring in all of the target objects.
        Expression backRef = builder.getManualQueryKey(getAttributeName() + "-back-ref", descriptorToUse);
        batchSelectionCriteria = backRef.twist(getSelectionCriteria(), builder);
        if (query.getSelectionCriteria() != null) {
            // For bug 2612567, any query can have batch attributes, so the
            // original selection criteria can be quite complex, with multiple
            // builders (i.e. for parallel selects).
            // Now uses cloneUsing(newBase) instead of rebuildOn(newBase).
            batchSelectionCriteria = batchSelectionCriteria.and(query.getSelectionCriteria().cloneUsing(backRef));
        }
        // to somehow keep all this code inside QueryKeyExpression.normalize.
        if (descriptorToUse.getQueryManager().getAdditionalJoinExpression() != null) {
            batchSelectionCriteria = batchSelectionCriteria.and(descriptorToUse.getQueryManager().getAdditionalJoinExpression().rebuildOn(backRef));
        }
        // Check for history and add history expression.
        if (descriptorToUse.getHistoryPolicy() != null) {
            if (query.getSession().getAsOfClause() != null) {
                backRef.asOf(query.getSession().getAsOfClause());
            } else if (batchQuery.getAsOfClause() == null) {
                backRef.asOf(AsOfClause.NO_CLAUSE);
            } else {
                backRef.asOf(batchQuery.getAsOfClause());
            }
            batchSelectionCriteria = batchSelectionCriteria.and(descriptorToUse.getHistoryPolicy().additionalHistoryExpression(backRef, backRef));
        }
    }
    batchQuery.setSelectionCriteria(batchSelectionCriteria);
    if (query.isDistinctComputed()) {
        // Only recompute if it has not already been set by the user
        batchQuery.setDistinctState(query.getDistinctState());
    }
    // Add batch reading attributes contained in the mapping's query.
    ReadQuery mappingQuery = this.selectionQuery;
    if (mappingQuery.isReadAllQuery()) {
        // CR#3238 clone these vectors so they will not grow with each call to the query. -TW
        batchQuery.setOrderByExpressions(new ArrayList<>(((ReadAllQuery) mappingQuery).getOrderByExpressions()));
        if (((ReadAllQuery) mappingQuery).hasBatchReadAttributes()) {
            for (Expression expression : ((ReadAllQuery) mappingQuery).getBatchReadAttributeExpressions()) {
                batchQuery.addBatchReadAttribute(expression);
            }
        }
    }
    // has been using inheritance and child descriptors can have different mappings.
    if (query.hasBatchReadAttributes()) {
        for (Expression expression : query.getBatchReadAttributeExpressions()) {
            ObjectExpression batchReadExpression = (ObjectExpression) expression;
            // Batch Read Attribute Expressions may not have initialized.
            ExpressionBuilder expressionBuilder = batchReadExpression.getBuilder();
            if (expressionBuilder.getQueryClass() == null) {
                expressionBuilder.setQueryClass(query.getReferenceClass());
            }
            if (expressionBuilder.getSession() == null) {
                expressionBuilder.setSession(query.getSession().getRootSession(null));
            }
        }
        // Computed nested batch attribute expressions, and add them to batch query.
        List<Expression> nestedExpressions = extractNestedExpressions(query.getBatchReadAttributeExpressions(), batchQuery.getExpressionBuilder());
        batchQuery.getBatchReadAttributeExpressions().addAll(nestedExpressions);
    }
    batchQuery.setBatchFetchType(batchType);
    batchQuery.setBatchFetchSize(query.getBatchFetchPolicy().getSize());
    // Allow subclasses to further prepare.
    postPrepareNestedBatchQuery(batchQuery, query);
    // Set nested fetch group.
    if (batchQuery.getDescriptor().hasFetchGroupManager()) {
        FetchGroup sourceFetchGroup = query.getExecutionFetchGroup();
        if (sourceFetchGroup != null) {
            FetchGroup targetFetchGroup = sourceFetchGroup.getGroup(getAttributeName());
            if (targetFetchGroup != null) {
                batchQuery.setFetchGroup(targetFetchGroup);
            }
        }
    }
    if (batchQuery.shouldPrepare()) {
        batchQuery.checkPrepare(query.getSession(), query.getTranslationRow());
    }
    batchQuery.setSession(null);
    return batchQuery;
}
Also used : BatchFetchType(org.eclipse.persistence.annotations.BatchFetchType) ClassDescriptor(org.eclipse.persistence.descriptors.ClassDescriptor) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) Expression(org.eclipse.persistence.expressions.Expression) ReportQuery(org.eclipse.persistence.queries.ReportQuery) ReadAllQuery(org.eclipse.persistence.queries.ReadAllQuery) FetchGroup(org.eclipse.persistence.queries.FetchGroup) ExpressionBuilder(org.eclipse.persistence.expressions.ExpressionBuilder) ObjectLevelReadQuery(org.eclipse.persistence.queries.ObjectLevelReadQuery) ReadQuery(org.eclipse.persistence.queries.ReadQuery) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression)

Example 8 with ObjectExpression

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

the class DirectCollectionMapping method getJoinCriteria.

/**
 * INTERNAL:
 * Returns the join criteria stored in the mapping selection query. This criteria
 * is used to read reference objects across the tables from the database.
 */
@Override
public Expression getJoinCriteria(ObjectExpression context, Expression base) {
    if (getHistoryPolicy() != null) {
        Expression result = super.getJoinCriteria(context, base);
        Expression historyCriteria = getHistoryPolicy().additionalHistoryExpression(context, base);
        if (result != null) {
            return result.and(historyCriteria);
        } else if (historyCriteria != null) {
            return historyCriteria;
        } else {
            return null;
        }
    } else {
        return super.getJoinCriteria(context, base);
    }
}
Also used : ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) Expression(org.eclipse.persistence.expressions.Expression) TableExpression(org.eclipse.persistence.internal.expressions.TableExpression)

Example 9 with ObjectExpression

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

the class DatabaseMapping method extractNestedNonAggregateExpressions.

/**
 * INTERNAL:
 * Extract the nested attribute expressions that apply to this mapping.
 * This is used for joining, and locking.
 * For aggregates return the nested foreign reference mapping, not the aggregate, as the aggregates are not joined,
 * and share their parent's query.
 *
 * @param expressions TODO
 * @param newRoot TODO
 * @param rootExpressionsAllowed true if newRoot itself can be one of the
 * expressions returned (used for locking)
 * @return TODO
 */
protected List<Expression> extractNestedNonAggregateExpressions(List<Expression> expressions, ExpressionBuilder newRoot, boolean rootExpressionsAllowed) {
    List<Expression> nestedExpressions = new ArrayList<>(expressions.size());
    /*
         * need to work on all expressions with at least 2 nestings off the base expression builder, excluding
         * aggregateObjectMapping expressions from the count (only ForeignReferenceMapping expressions count).  For those
         * expressions, 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;
        boolean done = false;
        ObjectExpression prevExpression = base;
        while (!base.getBaseExpression().isExpressionBuilder() && !done) {
            base = (ObjectExpression) base.getBaseExpression();
            while (!base.isExpressionBuilder() && (base.getMapping() != null && base.getMapping().isAggregateObjectMapping())) {
                base = (ObjectExpression) base.getBaseExpression();
            }
            if (base.isExpressionBuilder()) {
                done = true;
                // use the one closest to the expression builder that wasn't an aggregate
                base = prevExpression;
            } else {
                prevExpression = base;
                afterBase = true;
            }
        }
        if (afterBase && base.getName().equals(getAttributeName())) {
            nestedExpressions.add(expression.rebuildOn(base, newRoot));
        } else if (rootExpressionsAllowed && expression.getBaseExpression().isExpressionBuilder() && expression.getName().equals(getAttributeName())) {
            nestedExpressions.add(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)

Example 10 with ObjectExpression

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

the class JoinedAttributeManager method addExpressionAndBaseToGroupedList.

/**
 * adds expression and its base expressions recursively to the expressionList in groups, so that an expression is never listed before
 * its base expression
 */
protected Expression addExpressionAndBaseToGroupedList(Expression expression, List expressionlist, Expression lastJoinedAttributeBaseExpression) {
    if (!expressionlist.contains(expression)) {
        int baseExpressionIndex = -1;
        // better than using instanceof BaseExpression.  If its not an objectExpression, it will get an exception in prepare anyway
        boolean sameBase = false;
        if ((expression.isObjectExpression())) {
            Expression baseExpression = ((BaseExpression) expression).getBaseExpression();
            // filter out aggregate expressions between this and the next node.
            while (!baseExpression.isExpressionBuilder() && ((QueryKeyExpression) baseExpression).getMapping().isAggregateMapping()) {
                baseExpression = ((BaseExpression) baseExpression).getBaseExpression();
            }
            if (baseExpression != null && !baseExpression.isExpressionBuilder()) {
                addExpressionAndBaseToGroupedList(baseExpression, expressionlist, lastJoinedAttributeBaseExpression);
                // EL bug 307497
                if (baseExpression != lastJoinedAttributeBaseExpression) {
                    baseExpressionIndex = getJoinedAttributeExpressions().indexOf(baseExpression);
                } else {
                    sameBase = true;
                }
            }
        }
        // EL bug 307497
        if (baseExpressionIndex == -1) {
            expressionlist.add(expression);
            if (!sameBase) {
                lastJoinedAttributeBaseExpression = expression;
            }
        } else {
            // Add attributeExpression at baseExpressionIndex + 1.
            expressionlist.add(baseExpressionIndex + 1, expression);
        }
    }
    return lastJoinedAttributeBaseExpression;
}
Also used : BaseExpression(org.eclipse.persistence.internal.expressions.BaseExpression) BaseExpression(org.eclipse.persistence.internal.expressions.BaseExpression) QueryKeyExpression(org.eclipse.persistence.internal.expressions.QueryKeyExpression) ObjectExpression(org.eclipse.persistence.internal.expressions.ObjectExpression) Expression(org.eclipse.persistence.expressions.Expression) 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