use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.
the class JoinedAttributeManager method getNestedJoinedMappingQuery.
/**
* INTERNAL:
* Returns the nested query corresponding to the expression.
* The passed expression should be either join mapping or joined attribute expression.
*/
public ObjectLevelReadQuery getNestedJoinedMappingQuery(Expression expression) {
// the first element of the list is the passed expression,
// next one is its base, ...
// the last one's base is ExpressionBuilder.
ObjectExpression currentExpression = (ObjectExpression) expression;
ArrayList<Expression> expressionBaseList = new ArrayList();
do {
// reference mappings on aggregates are added to the parent's joinAttributeManager
if (!currentExpression.getMapping().isAggregateObjectMapping()) {
expressionBaseList.add(currentExpression);
}
currentExpression = (ObjectExpression) currentExpression.getBaseExpression();
} while (!currentExpression.isExpressionBuilder());
// the last expression in the list is not nested - its mapping should have corresponding nestedQuery.
DatabaseMapping currentMapping = ((QueryKeyExpression) expressionBaseList.get(expressionBaseList.size() - 1)).getMapping();
ObjectLevelReadQuery nestedQuery = getJoinedMappingQueries_().get(currentMapping);
// the last step is the passed expression (first on the list) getting nested query corresponding to its mapping.
for (int i = expressionBaseList.size() - 2; i >= 0; i--) {
currentMapping = ((QueryKeyExpression) expressionBaseList.get(i)).getMapping();
nestedQuery = nestedQuery.getJoinedAttributeManager().getJoinedMappingQueries_().get(currentMapping);
}
return nestedQuery;
}
use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.
the class ObjectLevelReadQuery method computeBatchReadAttributes.
/**
* INTERNAL:
* Compute the cache batched attributes.
* Used to recompute batched attributes for nested aggregate queries.
*/
public void computeBatchReadAttributes() {
List<Expression> batchReadAttributeExpressions = getBatchReadAttributeExpressions();
this.batchFetchPolicy.setAttributes(new ArrayList(batchReadAttributeExpressions.size()));
int size = batchReadAttributeExpressions.size();
for (int index = 0; index < size; index++) {
ObjectExpression objectExpression = (ObjectExpression) batchReadAttributeExpressions.get(index);
// Expression may not have been initialized.
ExpressionBuilder builder = objectExpression.getBuilder();
if (builder.getSession() == null) {
builder.setSession(getSession().getRootSession(null));
}
if (builder.getQueryClass() == null) {
builder.setQueryClass(getReferenceClass());
}
// PERF: Cache join attribute names.
ObjectExpression baseExpression = objectExpression;
while (!baseExpression.getBaseExpression().isExpressionBuilder()) {
baseExpression = (ObjectExpression) baseExpression.getBaseExpression();
}
this.batchFetchPolicy.getAttributes().add(baseExpression.getName());
}
}
use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.
the class ObjectLevelReadQuery method computeNestedQueriesForBatchReadExpressions.
/**
* INTERNAL:
* This method is used when computing the nested queries for batch read mappings.
* It recurses computing the nested mapping queries.
*/
protected void computeNestedQueriesForBatchReadExpressions(List<Expression> batchReadExpressions) {
int size = batchReadExpressions.size();
for (int index = 0; index < size; index++) {
ObjectExpression objectExpression = (ObjectExpression) batchReadExpressions.get(index);
// Expression may not have been initialized.
ExpressionBuilder builder = objectExpression.getBuilder();
if (builder.getSession() == null) {
builder.setSession(getSession().getRootSession(null));
}
if (builder.getQueryClass() == null) {
builder.setQueryClass(getReferenceClass());
}
// PERF: Cache join attribute names.
ObjectExpression baseExpression = objectExpression;
while (!baseExpression.getBaseExpression().isExpressionBuilder()) {
baseExpression = (ObjectExpression) baseExpression.getBaseExpression();
}
this.batchFetchPolicy.getAttributes().add(baseExpression.getName());
DatabaseMapping mapping = baseExpression.getMapping();
if ((mapping != null) && mapping.isAggregateObjectMapping()) {
// Also prepare the nested aggregate queries, as aggregates do not have their own query.
baseExpression = objectExpression.getFirstNonAggregateExpressionAfterExpressionBuilder(new ArrayList(2));
mapping = baseExpression.getMapping();
}
if ((mapping != null) && mapping.isForeignReferenceMapping()) {
if (!this.batchFetchPolicy.getMappingQueries().containsKey(mapping)) {
// 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.
this.batchFetchPolicy.getMappingQueries().put(mapping, nestedQuery);
}
}
}
}
use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.
the class JoinedAttributeManager method computeIndexesForJoinedExpressions.
/**
* This method is used when computing the indexes for joined mappings. It iterates through a list of join
* expressions and adds an index that represents where the fields represented by that expression will appear
* in the row returned by a read query.
* Method {@link #computeNestedQueriesForJoinedExpressions(List, AbstractSession, ObjectLevelReadQuery)}
* must be already called.
* @param joinedExpressions Join expressions {@link List}.
* @param currentIndex Current joined mapping index.
* @param session Current session.
* @return Current joined mapping index updated.
*/
protected int computeIndexesForJoinedExpressions(final List joinedExpressions, int currentIndex, final AbstractSession session) {
for (int index = 0; index < joinedExpressions.size(); index++) {
final ObjectExpression objectExpression = (ObjectExpression) joinedExpressions.get(index);
final DatabaseMapping mapping = objectExpression.getMapping();
// Only store the index if this is the local expression to avoid it being added multiple times.
// This means the base local expression must be first on the list, followed by nested expressions.
final ObjectExpression localExpression = objectExpression.getFirstNonAggregateExpressionAfterExpressionBuilder(new ArrayList(1));
if ((localExpression == objectExpression) && (mapping != null) && mapping.isForeignReferenceMapping()) {
getJoinedMappingIndexes_().put(mapping, currentIndex);
}
final ClassDescriptor descriptor = mapping.getReferenceDescriptor();
int numberOfFields = 0;
if (descriptor == null) {
// Direct-collection mappings do not have descriptor.
if (mapping.isDirectCollectionMapping()) {
numberOfFields = 1;
}
} else {
final ObjectLevelReadQuery nestedQuery = getNestedJoinedMappingQuery(objectExpression);
FetchGroup fetchGroup = null;
if (descriptor.hasFetchGroupManager()) {
fetchGroup = nestedQuery.getExecutionFetchGroup();
}
if (fetchGroup != null) {
numberOfFields = nestedQuery.getFetchGroupNonNestedFieldsSet(mapping).size();
} else {
if (objectExpression.isQueryKeyExpression() && objectExpression.isUsingOuterJoinForMultitableInheritance()) {
numberOfFields = descriptor.getAllSelectionFields(nestedQuery).size();
} else if (objectExpression.isQueryKeyExpression() && objectExpression.getDescriptor() != null && objectExpression.getDescriptor().hasInheritance() && objectExpression.getDescriptor().getInheritancePolicy().shouldReadSubclasses()) {
numberOfFields = descriptor.getAllFields().size();
} else {
numberOfFields = descriptor.getSelectionFields(nestedQuery).size();
}
}
}
if (mapping.isCollectionMapping()) {
// map keys are indexed within the collection's row.
// Therefore we use an offset from within the collections row
numberOfFields += mapping.getContainerPolicy().updateJoinedMappingIndexesForMapKey(getJoinedMappingIndexes_(), numberOfFields);
}
currentIndex = currentIndex + numberOfFields;
}
return currentIndex;
}
use of org.eclipse.persistence.internal.expressions.ObjectExpression in project eclipselink by eclipse-ee4j.
the class JoinedAttributeManager method setupLockingClauseForJoinedExpressions.
/**
* Used for joining in conjunction with pessimistic locking.
* Iterate through a list of joined expressions and ensure expression is set on the locking
* clause for each expression that represents a pessimisically locked descriptor.
*/
private ForUpdateOfClause setupLockingClauseForJoinedExpressions(List joinedExpressions, AbstractSession session, ForUpdateOfClause lockingClause) {
// if any of them have pessimistic locking defined on the descriptor.
for (Iterator e = joinedExpressions.iterator(); e.hasNext(); ) {
Expression expression = (Expression) e.next();
// Expression has not yet been validated.
if (expression.isObjectExpression()) {
ObjectExpression joinedAttribute = (ObjectExpression) expression;
// Expression may not have been initialized.
joinedAttribute.getBuilder().setSession(session.getRootSession(null));
if (joinedAttribute.getBuilder().getQueryClass() == null) {
joinedAttribute.getBuilder().setQueryClass(descriptor.getJavaClass());
}
ClassDescriptor nestedDescriptor = joinedAttribute.getDescriptor();
// expression may not be valid, no descriptor, validation occurs later.
if (nestedDescriptor == null) {
return lockingClause;
}
if (nestedDescriptor.hasPessimisticLockingPolicy()) {
if (lockingClause == null) {
lockingClause = new ForUpdateOfClause();
lockingClause.setLockMode(nestedDescriptor.getCMPPolicy().getPessimisticLockingPolicy().getLockingMode());
}
lockingClause.addLockedExpression(joinedAttribute);
}
}
}
return lockingClause;
}
Aggregations