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));
}
// Since a manual query key expression does not really get normalized,
// it must get its additional expressions added in here. Probably best
// 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<Expression>(((ReadAllQuery)mappingQuery).getOrderByExpressions()));
if (((ReadAllQuery)mappingQuery).hasBatchReadAttributes()) {
for (Expression expression : ((ReadAllQuery)mappingQuery).getBatchReadAttributeExpressions()) {
batchQuery.addBatchReadAttribute(expression);
}
}
}
// Bug 385700 - Populate session & query class if not initialized by
// ObjectLevelReadQuery.computeBatchReadMappingQueries() in case batch query
// 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) {
((ObjectLevelReadQuery)batchQuery).setFetchGroup(targetFetchGroup);
}
}
}
if (batchQuery.shouldPrepare()) {
batchQuery.checkPrepare(query.getSession(), query.getTranslationRow());
}
batchQuery.setSession(null);
return batchQuery;
}