/** * INTERNAL: * Return if the unit of work should by-pass the session cache. * Objects will be built in the unit of work, and never merged into the session cache. */ public boolean shouldIsolateObjectsInUnitOfWork() { return getCachePolicy().shouldIsolateObjectsInUnitOfWork(); }
/** * INTERNAL: * Return if the unit of work should by-pass the session cache. * Objects will be built in the unit of work, and never merged into the session cache. */ public boolean shouldIsolateObjectsInUnitOfWork() { return getCachePolicy().shouldIsolateObjectsInUnitOfWork(); }
/** * INTERNAL: * Return whether this project has a descriptor that is both Isolated and * has a cache isolation level other than ISOLATE_CACHE_ALWAYS * @return */ public boolean hasIsolatedCacheClassWithoutUOWIsolation(){ // checked cached boolean to avoid iteration if (!hasIsolatedClasses){ return false; } Iterator<ClassDescriptor> i = orderedDescriptors.iterator(); while (i.hasNext()){ ClassDescriptor descriptor = i.next(); if (descriptor.getCachePolicy().isIsolated() && !descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) { return true; } } return false; }
/** * INTERNAL: * Return whether this project has a descriptor that is both Isolated and * has a cache isolation level other than ISOLATE_CACHE_ALWAYS * @return */ public boolean hasIsolatedCacheClassWithoutUOWIsolation(){ // checked cached boolean to avoid iteration if (!hasIsolatedClasses){ return false; } Iterator<ClassDescriptor> i = orderedDescriptors.iterator(); while (i.hasNext()){ ClassDescriptor descriptor = i.next(); if (descriptor.getCachePolicy().isIsolated() && !descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) { return true; } } return false; }
/** * INTERNAL: * Remove objects from parent's identity map. */ protected void postMergeChanges(Set classesChanged) { //bug 4730595: objects removed during flush are not removed from the cache during commit if (this.unitOfWorkChangeSet.hasDeletedObjects()) { Map deletedObjects = this.unitOfWorkChangeSet.getDeletedObjects(); for (Iterator removedObjects = deletedObjects.keySet().iterator(); removedObjects.hasNext(); ) { ObjectChangeSet removedObjectChangeSet = (ObjectChangeSet) removedObjects.next(); Object primaryKey = removedObjectChangeSet.getId(); ClassDescriptor descriptor = removedObjectChangeSet.getDescriptor(); // PERF: Do not remove if uow is isolated. if (!descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) { this.parent.getIdentityMapAccessorInstance().removeFromIdentityMap(primaryKey, descriptor.getJavaClass(), descriptor, removedObjectChangeSet.getUnitOfWorkClone()); classesChanged.add(descriptor.getJavaClass()); } } } }
/** * INTERNAL: * Remove objects from parent's identity map. */ protected void postMergeChanges(Set classesChanged) { //bug 4730595: objects removed during flush are not removed from the cache during commit if (this.unitOfWorkChangeSet.hasDeletedObjects()) { Map deletedObjects = this.unitOfWorkChangeSet.getDeletedObjects(); for (Iterator removedObjects = deletedObjects.keySet().iterator(); removedObjects.hasNext(); ) { ObjectChangeSet removedObjectChangeSet = (ObjectChangeSet) removedObjects.next(); Object primaryKey = removedObjectChangeSet.getId(); ClassDescriptor descriptor = removedObjectChangeSet.getDescriptor(); // PERF: Do not remove if uow is isolated. if (!descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) { this.parent.getIdentityMapAccessorInstance().removeFromIdentityMap(primaryKey, descriptor.getJavaClass(), descriptor, removedObjectChangeSet.getUnitOfWorkClone()); classesChanged.add(descriptor.getJavaClass()); } } } }
if (descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork()) { continue;
/** * For executing all reads on the UnitOfWork, the session when building * objects from rows will now be the UnitOfWork. Useful if the rows were * read via a dirty write connection and we want to avoid putting uncommitted * data in the global cache. * <p> * Decides whether to call either buildWorkingCopyCloneFromRow (bypassing * shared cache) or buildWorkingCopyCloneNormally (placing the result in the * shared cache). */ protected Object buildObjectInUnitOfWork(ObjectBuildingQuery query, JoinedAttributeManager joinManager, AbstractRecord databaseRow, UnitOfWorkImpl unitOfWork, Object primaryKey, CacheKey preFetchedCacheKey, ClassDescriptor concreteDescriptor) throws DatabaseException, QueryException { // When in transaction we are reading via the write connection // and so do not want to corrupt the shared cache with dirty objects. // Hence we build and refresh clones directly from the database row. // PERF: Allow the session cached to still be used after early transaction if isolation setting has been set. CachePolicy cachePolicy = concreteDescriptor.getCachePolicy(); if (!cachePolicy.shouldUseSessionCacheInUnitOfWorkEarlyTransaction()) { if (((unitOfWork.hasCommitManager() && unitOfWork.getCommitManager().isActive()) || unitOfWork.wasTransactionBegunPrematurely() || cachePolicy.shouldIsolateObjectsInUnitOfWork() || cachePolicy.shouldIsolateProtectedObjectsInUnitOfWork() || query.shouldStoreBypassCache()) && (!unitOfWork.isClassReadOnly(concreteDescriptor.getJavaClass(), concreteDescriptor))) { // It is easier to switch once to the correct builder here. return concreteDescriptor.getObjectBuilder().buildWorkingCopyCloneFromRow(query, joinManager, databaseRow, unitOfWork, primaryKey, preFetchedCacheKey); } } return buildWorkingCopyCloneNormally(query, databaseRow, unitOfWork, primaryKey, preFetchedCacheKey, concreteDescriptor, joinManager); }
/** * For executing all reads on the UnitOfWork, the session when building * objects from rows will now be the UnitOfWork. Useful if the rows were * read via a dirty write connection and we want to avoid putting uncommitted * data in the global cache. * <p> * Decides whether to call either buildWorkingCopyCloneFromRow (bypassing * shared cache) or buildWorkingCopyCloneNormally (placing the result in the * shared cache). */ protected Object buildObjectInUnitOfWork(ObjectBuildingQuery query, JoinedAttributeManager joinManager, AbstractRecord databaseRow, UnitOfWorkImpl unitOfWork, Object primaryKey, CacheKey preFetchedCacheKey, ClassDescriptor concreteDescriptor) throws DatabaseException, QueryException { // When in transaction we are reading via the write connection // and so do not want to corrupt the shared cache with dirty objects. // Hence we build and refresh clones directly from the database row. // PERF: Allow the session cached to still be used after early transaction if isolation setting has been set. CachePolicy cachePolicy = concreteDescriptor.getCachePolicy(); if (!cachePolicy.shouldUseSessionCacheInUnitOfWorkEarlyTransaction()) { if (((unitOfWork.hasCommitManager() && unitOfWork.getCommitManager().isActive()) || unitOfWork.wasTransactionBegunPrematurely() || cachePolicy.shouldIsolateObjectsInUnitOfWork() || cachePolicy.shouldIsolateProtectedObjectsInUnitOfWork() || query.shouldStoreBypassCache()) && (!unitOfWork.isClassReadOnly(concreteDescriptor.getJavaClass(), concreteDescriptor))) { // It is easier to switch once to the correct builder here. return concreteDescriptor.getObjectBuilder().buildWorkingCopyCloneFromRow(query, joinManager, databaseRow, unitOfWork, primaryKey, preFetchedCacheKey); } } return buildWorkingCopyCloneNormally(query, databaseRow, unitOfWork, primaryKey, preFetchedCacheKey, concreteDescriptor, joinManager); }
&& ((!(unitOfWork.hasCommitManager() && unitOfWork.getCommitManager().isActive()) && ! unitOfWork.wasTransactionBegunPrematurely() && !this.descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() && ! this.descriptor.getCachePolicy().shouldIsolateProtectedObjectsInUnitOfWork()) || (unitOfWork.isClassReadOnly(this.getReferenceClass(), this.getDescriptor())))){
&& ((!(unitOfWork.hasCommitManager() && unitOfWork.getCommitManager().isActive()) && ! unitOfWork.wasTransactionBegunPrematurely() && !this.descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() && ! this.descriptor.getCachePolicy().shouldIsolateProtectedObjectsInUnitOfWork()) || (unitOfWork.isClassReadOnly(this.getReferenceClass(), this.getDescriptor())))){
/** * INTERNAL: * Initialize the cache isolation setting. * This may need to be called multiple times as notifyReferencingDescriptorsOfIsolation() can change the cache isolation. */ public void postInitialize(ClassDescriptor descriptor, AbstractSession session) throws DescriptorException { if (!isSharedIsolation()) { descriptor.notifyReferencingDescriptorsOfIsolation(session); } // PERF: If using isolated cache, then default uow isolation to always (avoids merge/double build). if ((getUnitOfWorkCacheIsolationLevel() == UNDEFINED_ISOLATATION) || this.wasDefaultUnitOfWorkCacheIsolationLevel) { this.wasDefaultUnitOfWorkCacheIsolationLevel = true; if (isIsolated()) { setUnitOfWorkCacheIsolationLevel(ISOLATE_CACHE_ALWAYS); } else if (isProtectedIsolation()) { setUnitOfWorkCacheIsolationLevel(ISOLATE_FROM_CLIENT_SESSION); } else { setUnitOfWorkCacheIsolationLevel(ISOLATE_NEW_DATA_AFTER_TRANSACTION); } } // Record that there is an isolated class in the project. if (!isSharedIsolation()) { session.getProject().setHasIsolatedClasses(true); } if (!shouldIsolateObjectsInUnitOfWork() && !descriptor.shouldBeReadOnly()) { session.getProject().setHasNonIsolatedUOWClasses(true); } }
/** * INTERNAL: * Initialize the cache isolation setting. * This may need to be called multiple times as notifyReferencingDescriptorsOfIsolation() can change the cache isolation. */ public void postInitialize(ClassDescriptor descriptor, AbstractSession session) throws DescriptorException { if (!isSharedIsolation()) { descriptor.notifyReferencingDescriptorsOfIsolation(session); } // PERF: If using isolated cache, then default uow isolation to always (avoids merge/double build). if ((getUnitOfWorkCacheIsolationLevel() == UNDEFINED_ISOLATATION) || this.wasDefaultUnitOfWorkCacheIsolationLevel) { this.wasDefaultUnitOfWorkCacheIsolationLevel = true; if (isIsolated()) { setUnitOfWorkCacheIsolationLevel(ISOLATE_CACHE_ALWAYS); } else if (isProtectedIsolation()) { setUnitOfWorkCacheIsolationLevel(ISOLATE_FROM_CLIENT_SESSION); } else { setUnitOfWorkCacheIsolationLevel(ISOLATE_NEW_DATA_AFTER_TRANSACTION); } } // Record that there is an isolated class in the project. if (!isSharedIsolation()) { session.getProject().setHasIsolatedClasses(true); } if (!shouldIsolateObjectsInUnitOfWork() && !descriptor.shouldBeReadOnly()) { session.getProject().setHasNonIsolatedUOWClasses(true); } }
if ((!unitOfWork.isNestedUnitOfWork()) && (this.descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() || isLockQuery()) || unitOfWork.shouldForceReadFromDB(this, null)) { return null;
if ((!unitOfWork.isNestedUnitOfWork()) && (this.descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() || isLockQuery()) || unitOfWork.shouldForceReadFromDB(this, null)) { return null;
ClassDescriptor descriptor = changeSetToWrite.getDescriptor(); if ((!isNestedUnitOfWork) && descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() ) { break;
ClassDescriptor descriptor = changeSetToWrite.getDescriptor(); if ((!isNestedUnitOfWork) && descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() ) { break;
/** * INTERNAL: * Used to initialize a remote descriptor. */ public void remoteInitialization(DistributedSession session) { // These cached settings on the project must be set even if descriptor is initialized. if (getHistoryPolicy() != null) { session.getProject().setHasGenericHistorySupport(true); } // Record that there is an isolated class in the project. if (!getCachePolicy().isSharedIsolation()) { session.getProject().setHasIsolatedClasses(true); } if (!getCachePolicy().shouldIsolateObjectsInUnitOfWork() && !shouldBeReadOnly()) { session.getProject().setHasNonIsolatedUOWClasses(true); } for (DatabaseMapping mapping : getMappings()) { mapping.remoteInitialization(session); } getEventManager().remoteInitialization(session); getInstantiationPolicy().initialize(session); getCopyPolicy().initialize(session); if (hasInheritance()) { getInheritancePolicy().remoteInitialization(session); } if (getCMPPolicy() != null) { getCMPPolicy().remoteInitialize(this, session); } }
/** * INTERNAL: * Used to initialize a remote descriptor. */ public void remoteInitialization(DistributedSession session) { // These cached settings on the project must be set even if descriptor is initialized. if (getHistoryPolicy() != null) { session.getProject().setHasGenericHistorySupport(true); } // Record that there is an isolated class in the project. if (!getCachePolicy().isSharedIsolation()) { session.getProject().setHasIsolatedClasses(true); } if (!getCachePolicy().shouldIsolateObjectsInUnitOfWork() && !shouldBeReadOnly()) { session.getProject().setHasNonIsolatedUOWClasses(true); } for (DatabaseMapping mapping : getMappings()) { mapping.remoteInitialization(session); } getEventManager().remoteInitialization(session); getInstantiationPolicy().initialize(session); getCopyPolicy().initialize(session); if (hasInheritance()) { getInheritancePolicy().remoteInitialization(session); } if (getCMPPolicy() != null) { getCMPPolicy().remoteInitialize(this, session); } }
boolean isIsolated = descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() || (descriptor.shouldIsolateObjectsInUnitOfWorkEarlyTransaction() && unitOfWork.wasTransactionBegunPrematurely());