use of org.eclipse.persistence.queries.ReadAllQuery in project eclipselink by eclipse-ee4j.
the class TransactionIsolationM2MBatchReadTest method test.
@Override
public void test() {
unitOfWork.beginEarlyTransaction();
ReadAllQuery query = new ReadAllQuery(Employee.class);
query.addBatchReadAttribute("projects");
Expression workersExp = (new ExpressionBuilder()).notEmpty("projects");
query.setSelectionCriteria(workersExp);
Vector workers = (Vector) unitOfWork.executeQuery(query);
Employee worker = (Employee) workers.elementAt(0);
Employee otherWorker = (Employee) workers.elementAt(1);
Vector workerProjects = worker.getProjects();
Vector otherWorkerProjects = otherWorker.getProjects();
// By now the test should have failed if it was going to fail.
// Try one more thing to make sure that they are batch read correctly.
strongAssert(workerProjects != otherWorkerProjects, "Everyone is getting back the same batched result.");
strongAssert(workerProjects != null, "The batched attribute [projects] was null.");
strongAssert(workerProjects.size() > 0, "The batched attribute [projects] was empty.");
Employee originalWorker = (Employee) getSession().readObject(worker);
verifyCloneHasSameProjectsAsOriginal(workerProjects, originalWorker.getProjects());
}
use of org.eclipse.persistence.queries.ReadAllQuery in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method buildProtectedObject.
/**
* Return an instance of the receivers javaClass. Set the attributes of an instance
* from the values stored in the database row.
*/
protected Object buildProtectedObject(boolean returnCacheKey, ObjectBuildingQuery query, AbstractRecord databaseRow, AbstractSession session, Object primaryKey, CacheKey preFetchedCacheKey, ClassDescriptor concreteDescriptor, JoinedAttributeManager joinManager) throws DatabaseException, QueryException {
Object cachedObject = null;
Object protectedObject = null;
// Cache key is used for object locking.
CacheKey cacheKey = null;
CacheKey sharedCacheKey = null;
// Keep track if we actually built/refresh the object.
boolean cacheHit = true;
try {
// Check if the objects exists in the identity map.
if (query.shouldMaintainCache() && (!query.shouldRetrieveBypassCache() || !query.shouldStoreBypassCache())) {
cacheKey = session.retrieveCacheKey(primaryKey, concreteDescriptor, joinManager, query);
protectedObject = cacheKey.getObject();
}
FetchGroup fetchGroup = query.getExecutionFetchGroup(concreteDescriptor);
FetchGroupManager fetchGroupManager = concreteDescriptor.getFetchGroupManager();
if (protectedObject == null || query.shouldRetrieveBypassCache()) {
cacheHit = false;
boolean domainWasMissing = protectedObject == null;
if (protectedObject == null || query.shouldStoreBypassCache()) {
if (query.isReadObjectQuery() && ((ReadObjectQuery) query).shouldLoadResultIntoSelectionObject()) {
protectedObject = ((ReadObjectQuery) query).getSelectionObject();
} else {
protectedObject = concreteDescriptor.getObjectBuilder().buildNewInstance();
}
}
// The object must be registered before building its attributes to resolve circular dependencies.
if (query.shouldMaintainCache() && !query.shouldStoreBypassCache()) {
if (domainWasMissing) {
// may have build a new domain even though there is one in the cache
cacheKey.setObject(protectedObject);
}
copyQueryInfoToCacheKey(cacheKey, query, databaseRow, session, concreteDescriptor);
} else if (cacheKey == null || (domainWasMissing && query.shouldRetrieveBypassCache())) {
cacheKey = new CacheKey(primaryKey);
cacheKey.setObject(protectedObject);
}
// The object must be registered before building its attributes to resolve circular dependencies.
if (query.shouldMaintainCache() && !query.shouldStoreBypassCache()) {
if (preFetchedCacheKey == null) {
sharedCacheKey = session.getParent().retrieveCacheKey(primaryKey, concreteDescriptor, joinManager, query);
} else {
sharedCacheKey = preFetchedCacheKey;
cacheKey.acquireLock(query);
}
if (sharedCacheKey.getObject() == null) {
sharedCacheKey = (CacheKey) buildObject(true, query, databaseRow, session.getParent(), primaryKey, preFetchedCacheKey, concreteDescriptor, joinManager);
cachedObject = sharedCacheKey.getObject();
}
}
concreteDescriptor.getObjectBuilder().buildAttributesIntoObject(protectedObject, sharedCacheKey, databaseRow, query, joinManager, fetchGroup, false, session);
// if !protected the returned object and the domain object are the same.
if (query.shouldMaintainCache() && !query.shouldStoreBypassCache()) {
// Set the fetch group to the domain object, after built.
if ((fetchGroup != null) && concreteDescriptor.hasFetchGroupManager()) {
EntityFetchGroup entityFetchGroup = concreteDescriptor.getFetchGroupManager().getEntityFetchGroup(fetchGroup);
if (entityFetchGroup != null) {
entityFetchGroup.setOnEntity(protectedObject, session);
}
}
}
// PERF: Cache the primary key and cache key if implements PersistenceEntity.
if (protectedObject instanceof PersistenceEntity) {
((PersistenceEntity) protectedObject)._persistence_setId(primaryKey);
}
} else {
if (query.isReadObjectQuery() && ((ReadObjectQuery) query).shouldLoadResultIntoSelectionObject()) {
copyInto(protectedObject, ((ReadObjectQuery) query).getSelectionObject());
protectedObject = ((ReadObjectQuery) query).getSelectionObject();
}
sharedCacheKey = session.getParent().retrieveCacheKey(primaryKey, concreteDescriptor, joinManager, query);
cachedObject = sharedCacheKey.getObject();
if (cachedObject == null) {
sharedCacheKey = (CacheKey) buildObject(true, query, databaseRow, session.getParent(), primaryKey, preFetchedCacheKey, concreteDescriptor, joinManager);
cachedObject = sharedCacheKey.getObject();
}
// check if the cached object has been invalidated
boolean isInvalidated = concreteDescriptor.getCacheInvalidationPolicy().isInvalidated(sharedCacheKey, query.getExecutionTime());
// fight to overwrite the object ( this also will avoid potential deadlock situations
if ((sharedCacheKey.getActiveThread() == Thread.currentThread()) && ((query.shouldRefreshIdentityMapResult() || concreteDescriptor.shouldAlwaysRefreshCache() || isInvalidated) && ((sharedCacheKey.getLastUpdatedQueryId() != query.getQueryId()) && !sharedCacheKey.isLockedByMergeManager()))) {
// need to refresh. shared cache instance
cacheHit = refreshObjectIfRequired(concreteDescriptor, sharedCacheKey, cachedObject, query, joinManager, databaseRow, session.getParent(), true);
// shared cache was refreshed and a refresh has been requested so lets refresh the protected object as well
refreshObjectIfRequired(concreteDescriptor, sharedCacheKey, protectedObject, query, joinManager, databaseRow, session, true);
} else if (fetchGroupManager != null && (fetchGroupManager.isPartialObject(protectedObject) && (!fetchGroupManager.isObjectValidForFetchGroup(protectedObject, fetchGroupManager.getEntityFetchGroup(fetchGroup))))) {
cacheHit = false;
// The fetched object is not sufficient for the fetch group of the query
// refresh attributes of the query's fetch group.
fetchGroupManager.unionEntityFetchGroupIntoObject(protectedObject, fetchGroupManager.getEntityFetchGroup(fetchGroup), session, false);
concreteDescriptor.getObjectBuilder().buildAttributesIntoObject(protectedObject, sharedCacheKey, databaseRow, query, joinManager, fetchGroup, false, session);
} else // may require some attributes' valueholders to be re-built.
if (joinManager != null && joinManager.hasJoinedAttributeExpressions()) {
// some queries like ObjRel do not support joining
loadJoinedAttributes(concreteDescriptor, cachedObject, sharedCacheKey, databaseRow, joinManager, query, false);
loadJoinedAttributes(concreteDescriptor, protectedObject, sharedCacheKey, databaseRow, joinManager, query, true);
} else if (query.isReadAllQuery() && ((ReadAllQuery) query).hasBatchReadAttributes()) {
loadBatchReadAttributes(concreteDescriptor, cachedObject, sharedCacheKey, databaseRow, query, joinManager, false);
loadBatchReadAttributes(concreteDescriptor, protectedObject, sharedCacheKey, databaseRow, query, joinManager, true);
}
}
} finally {
if (query.shouldMaintainCache()) {
if (cacheKey != null) {
// cacheKey.getObject() may be null.
if (cacheKey.getObject() != null) {
cacheKey.updateAccess();
}
// PERF: Only use deferred locking if required.
if (query.requiresDeferredLocks()) {
cacheKey.releaseDeferredLock();
} else {
cacheKey.release();
}
}
if (sharedCacheKey != null) {
// sharedCacheKey() may be null.
if (sharedCacheKey.getObject() != null) {
sharedCacheKey.updateAccess();
}
// PERF: Only use deferred locking if required.
if (query.requiresDeferredLocks()) {
sharedCacheKey.releaseDeferredLock();
} else {
sharedCacheKey.release();
}
}
}
}
if (!cacheHit) {
concreteDescriptor.getObjectBuilder().instantiateEagerMappings(protectedObject, session);
}
if (session.getProject().allowExtendedCacheLogging() && cacheKey != null && cacheKey.getObject() != null) {
session.log(SessionLog.FINEST, SessionLog.CACHE, "cache_item_creation", new Object[] { protectedObject.getClass(), primaryKey, Thread.currentThread().getId(), Thread.currentThread().getName() });
}
if (returnCacheKey) {
return cacheKey;
} else {
return protectedObject;
}
}
use of org.eclipse.persistence.queries.ReadAllQuery in project eclipselink by eclipse-ee4j.
the class ObjectBuilder method loadBatchReadAttributes.
protected void loadBatchReadAttributes(ClassDescriptor concreteDescriptor, Object sourceObject, CacheKey cacheKey, AbstractRecord databaseRow, ObjectBuildingQuery query, JoinedAttributeManager joinManager, boolean isTargetProtected) {
boolean useOnlyMappingsExcludedFromSOP = false;
if (concreteDescriptor.hasSerializedObjectPolicy() && query.shouldUseSerializedObjectPolicy()) {
// if true then sopObject has not been deserialized, that means sourceObject has been cached.
useOnlyMappingsExcludedFromSOP = databaseRow.get(concreteDescriptor.getSerializedObjectPolicy().getField()) != null;
}
boolean isUntriggeredResultSetRecord = databaseRow instanceof ResultSetRecord && ((ResultSetRecord) databaseRow).hasResultSet();
List<Expression> batchExpressions = ((ReadAllQuery) query).getBatchReadAttributeExpressions();
int size = batchExpressions.size();
for (int index = 0; index < size; index++) {
QueryKeyExpression queryKeyExpression = (QueryKeyExpression) batchExpressions.get(index);
// Only worry about immediate attributes.
if (queryKeyExpression.getBaseExpression().isExpressionBuilder()) {
DatabaseMapping mapping = getMappingForAttributeName(queryKeyExpression.getName());
if (mapping == null) {
throw ValidationException.missingMappingForAttribute(concreteDescriptor, queryKeyExpression.getName(), this.toString());
} else {
if (!useOnlyMappingsExcludedFromSOP || mapping.isOutSopObject()) {
// Bug 4230655 - do not replace instantiated valueholders.
Object attributeValue = mapping.getAttributeValueFromObject(sourceObject);
if ((attributeValue != null) && mapping.isForeignReferenceMapping() && ((ForeignReferenceMapping) mapping).usesIndirection() && (!((ForeignReferenceMapping) mapping).getIndirectionPolicy().objectIsInstantiated(attributeValue))) {
if (isUntriggeredResultSetRecord && mapping.isObjectReferenceMapping() && ((ObjectReferenceMapping) mapping).isForeignKeyRelationship() && !mapping.isPrimaryKeyMapping()) {
// still need to extract values from ResultSet for foreign key fields.
for (DatabaseField field : mapping.getFields()) {
// extract the values from ResultSet into the row
databaseRow.get(field);
}
}
AbstractSession session = query.getExecutionSession();
mapping.readFromRowIntoObject(databaseRow, joinManager, sourceObject, cacheKey, query, query.getExecutionSession(), isTargetProtected);
session.getIdentityMapAccessorInstance().getIdentityMap(concreteDescriptor).lazyRelationshipLoaded(sourceObject, (ValueHolderInterface) ((ForeignReferenceMapping) mapping).getIndirectionPolicy().getOriginalValueHolder(attributeValue, session), (ForeignReferenceMapping) mapping);
}
}
}
}
}
}
use of org.eclipse.persistence.queries.ReadAllQuery 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;
}
use of org.eclipse.persistence.queries.ReadAllQuery in project eclipselink by eclipse-ee4j.
the class DirectMapMapping method initializeSelectionStatement.
@Override
protected void initializeSelectionStatement(AbstractSession session) {
if (this.selectionQuery.isReadAllQuery()) {
((ReadAllQuery) this.selectionQuery).addAdditionalField(getDirectField().clone());
} else {
SQLSelectStatement statement = (SQLSelectStatement) this.selectionQuery.getSQLStatement();
statement.addTable(getReferenceTable());
statement.addField(getDirectField().clone());
getContainerPolicy().addAdditionalFieldsToQuery(this.selectionQuery, getAdditionalFieldsBaseExpression(this.selectionQuery));
statement.normalize(session, null);
}
if (this.selectionQuery.isDirectReadQuery()) {
((DirectReadQuery) this.selectionQuery).setResultType(DataReadQuery.MAP);
}
}
Aggregations