/** * INTERNAL: This method is used when computing the nested queries for batch read mappings. It * recurses computing the nested mapping queries. */ protected void computeNestedQueriesForBatchReadExpressions(Vector batchReadExpressions) { for (int index = 0; index < batchReadExpressions.size(); index++) { ObjectExpression objectExpression = (ObjectExpression) batchReadExpressions.get(index); // Expression may not have been initialized. ExpressionBuilder builder = objectExpression.getBuilder(); builder.setSession(getSession().getRootSession(null)); builder.setQueryClass(getReferenceClass()); // PERF: Cache join attribute names. ObjectExpression baseExpression = objectExpression; while (!baseExpression.getBaseExpression().isExpressionBuilder()) { baseExpression = (ObjectExpression) baseExpression.getBaseExpression(); } this.batchReadAttributes.add(baseExpression.getName()); // Ignore nested if (objectExpression.getBaseExpression().isExpressionBuilder()) { DatabaseMapping mapping = objectExpression.getMapping(); if ((mapping != null) && mapping.isForeignReferenceMapping()) { // A nested query must be built to pass to the descriptor that looks like the real query // execution would. ReadQuery nestedQuery = ((ForeignReferenceMapping) mapping).prepareNestedBatchQuery(this); // Register the nested query to be used by the mapping for all the objects. getBatchReadMappingQueries().put(mapping, nestedQuery); } } } }
/** * INTERNAL: Parses an expression to return the first non-AggregateObjectMapping expression after * the base ExpressionBuilder. This is used by joining and batch fetch to get the list of mappings * that really need to be processed (non-aggregates). * * @param aggregateMappingsEncountered - collection of aggregateObjectMapping expressions * encountered in the returned expression between the first expression and the * ExpressionBuilder * @return first non-AggregateObjectMapping expression after the base ExpressionBuilder from the * fullExpression */ public ObjectExpression getFirstNonAggregateExpressionAfterExpressionBuilder( List aggregateMappingsEncountered) { boolean done = false; ObjectExpression baseExpression = this; ObjectExpression prevExpression = this; while (!baseExpression.getBaseExpression().isExpressionBuilder() && !done) { baseExpression = (ObjectExpression) baseExpression.getBaseExpression(); while (!baseExpression.isExpressionBuilder() && baseExpression.getMapping().isAggregateObjectMapping()) { aggregateMappingsEncountered.add(baseExpression.getMapping()); baseExpression = (ObjectExpression) baseExpression.getBaseExpression(); } if (baseExpression.isExpressionBuilder()) { done = true; // use the one closest to the expression builder that wasn't an aggregate baseExpression = prevExpression; } else { prevExpression = baseExpression; } } return baseExpression; }