/** * OBSOLETE: * Set the type of cache coordination that will be used on objects of this type. Possible values * are:<ul> * <li>SEND_OBJECT_CHANGES * <li>INVALIDATE_CHANGED_OBJECTS * <li>SEND_NEW_OBJECTS_WITH_CHANGES * <li>DO_NOT_SEND_CHANGES</ul> * Note: Cache Synchronization type cannot be altered for descriptors that are set as isolated using * the setIsIsolated method.<p> * This has been replaced by setCacheCoordinationType(). * @see #setCacheCoordinationType(CacheCoordinationType) * @param type int The synchronization type for this descriptor */ public void setCacheSynchronizationType(int type) { // bug 3587273 if (!isIsolated()) { cacheSynchronizationType = type; } }
/** * OBSOLETE: * Set the type of cache coordination that will be used on objects of this type. Possible values * are:<ul> * <li>SEND_OBJECT_CHANGES * <li>INVALIDATE_CHANGED_OBJECTS * <li>SEND_NEW_OBJECTS_WITH_CHANGES * <li>DO_NOT_SEND_CHANGES</ul> * Note: Cache Synchronization type cannot be altered for descriptors that are set as isolated using * the setIsIsolated method.<p> * This has been replaced by setCacheCoordinationType(). * @see #setCacheCoordinationType(CacheCoordinationType) * @param type int The synchronization type for this descriptor */ public void setCacheSynchronizationType(int type) { // bug 3587273 if (!isIsolated()) { cacheSynchronizationType = type; } }
/** * PUBLIC: * Returns true if the descriptor represents an isolated class */ public boolean isIsolated() { return getCachePolicy().isIsolated(); }
/** * PUBLIC: * Returns true if the descriptor represents an isolated class */ public boolean isIsolated() { return getCachePolicy().isIsolated(); }
/** * INTERNAL: * Return whether this mapping should be traversed when we are locking. */ @Override public boolean isLockableMapping(){ return !(this.usesIndirection()) && !referenceDescriptor.getCachePolicy().isIsolated(); }
/** * INTERNAL: * Return whether this mapping should be traversed when we are locking. */ @Override public boolean isLockableMapping(){ return !(this.usesIndirection()) && !referenceDescriptor.getCachePolicy().isIsolated(); }
/** * 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: * This method will be used to update the query with any settings required * For this session. It can also be used to validate execution. */ @Override public void validateQuery(DatabaseQuery query) { if (query.isObjectLevelReadQuery() && ((query.getDescriptor().getCachePolicy().isIsolated()) || ((ObjectLevelReadQuery)query).shouldUseExclusiveConnection())) { throw QueryException.isolatedQueryExecutedOnServerSession(); } }
/** * INTERNAL: * This method will be used to update the query with any settings required * For this session. It can also be used to validate execution. */ @Override public void validateQuery(DatabaseQuery query) { if (query.isObjectLevelReadQuery() && ((query.getDescriptor().getCachePolicy().isIsolated()) || ((ObjectLevelReadQuery)query).shouldUseExclusiveConnection())) { throw QueryException.isolatedQueryExecutedOnServerSession(); } }
/** * INTERNAL: * Initialize the state of mapping. */ @Override public void initialize(AbstractSession session) throws DescriptorException { super.initialize(session); if (this.isPrivateOwned && (this.descriptor != null)) { this.descriptor.addMappingsPostCalculateChanges(this); } initializeReferenceDescriptor(session); initializeSelectionQuery(session); this.indirectionPolicy.initialize(); if ((this.referenceDescriptor != null) && this.referenceDescriptor.getCachePolicy().isIsolated()) { this.isCacheable = false; } }
/** * INTERNAL: * Initialize the state of mapping. */ @Override public void initialize(AbstractSession session) throws DescriptorException { super.initialize(session); //474752 : InitializeReferenceDescriptor before //addMappingsPostCalculateChanges initializeReferenceDescriptor(session); if (this.isPrivateOwned && (this.descriptor != null)) { this.descriptor.addMappingsPostCalculateChanges(this); } initializeSelectionQuery(session); this.indirectionPolicy.initialize(); if ((this.referenceDescriptor != null) && this.referenceDescriptor.getCachePolicy().isIsolated()) { this.isCacheable = false; } }
/** * INTERNAL: * Returns the appropriate IdentityMap session for this descriptor. Sessions can be * chained and each session can have its own Cache/IdentityMap. Entities can be stored * at different levels based on Cache Isolation. This method will return the correct Session * for a particular Entity class based on the Isolation Level and the attributes provided. * <p> * @param canReturnSelf true when method calls itself. If the path * starting at <code>this</code> is acceptable. Sometimes true if want to * move to the first valid session, i.e. executing on ClientSession when really * should be on ServerSession. * @param terminalOnly return the last session in the chain where the Enitity is stored. * @return Session with the required IdentityMap */ @Override public AbstractSession getParentIdentityMapSession(ClassDescriptor descriptor, boolean canReturnSelf, boolean terminalOnly) { if (canReturnSelf && (descriptor == null || descriptor.getCachePolicy().isIsolated() || (descriptor.getCachePolicy().isProtectedIsolation() && !descriptor.shouldIsolateProtectedObjectsInUnitOfWork() && !terminalOnly))){ return this; } return getParent().getParentIdentityMapSession(descriptor, canReturnSelf, terminalOnly); }
/** * INTERNAL: * Returns the appropriate IdentityMap session for this descriptor. Sessions can be * chained and each session can have its own Cache/IdentityMap. Entities can be stored * at different levels based on Cache Isolation. This method will return the correct Session * for a particular Entity class based on the Isolation Level and the attributes provided. * <p> * @param canReturnSelf true when method calls itself. If the path * starting at <code>this</code> is acceptable. Sometimes true if want to * move to the first valid session, i.e. executing on ClientSession when really * should be on ServerSession. * @param terminalOnly return the last session in the chain where the Enitity is stored. * @return Session with the required IdentityMap */ @Override public AbstractSession getParentIdentityMapSession(ClassDescriptor descriptor, boolean canReturnSelf, boolean terminalOnly) { if (canReturnSelf && (descriptor == null || descriptor.getCachePolicy().isIsolated() || (descriptor.getCachePolicy().isProtectedIsolation() && !descriptor.shouldIsolateProtectedObjectsInUnitOfWork() && !terminalOnly))){ return this; } return getParent().getParentIdentityMapSession(descriptor, canReturnSelf, terminalOnly); }
/** * INTERNAL: Answers if this query is an isolated query and must be * executed locally. */ protected boolean isIsolatedQuery(DatabaseQuery query) { query.checkDescriptor(this); ClassDescriptor descriptor = query.getDescriptor(); if (query.isDataModifyQuery() || query.isDataReadQuery() || (descriptor != null && descriptor.getCachePolicy().isIsolated()) || (query.isObjectBuildingQuery() && ((ObjectBuildingQuery)query).shouldUseExclusiveConnection())) { // For CR#4334 if in transaction stay on client session. // That way client's write accessor will be used for all queries. // This is to preserve transaction isolation levels. // also if this is an isolated class and we are in an isolated session //load locally. return true; } return false; }
/** * INTERNAL: Answers if this query is an isolated query and must be * executed locally. */ protected boolean isIsolatedQuery(DatabaseQuery query) { query.checkDescriptor(this); ClassDescriptor descriptor = query.getDescriptor(); if (query.isDataModifyQuery() || query.isDataReadQuery() || (descriptor != null && descriptor.getCachePolicy().isIsolated()) || (query.isObjectBuildingQuery() && ((ObjectBuildingQuery)query).shouldUseExclusiveConnection())) { // For CR#4334 if in transaction stay on client session. // That way client's write accessor will be used for all queries. // This is to preserve transaction isolation levels. // also if this is an isolated class and we are in an isolated session //load locally. return true; } return false; }
/** * ADVANCED: * Return the object from the identity with the primary and class. */ @Override public Object getFromIdentityMap(Object primaryKey, Object object, Class theClass, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor) { if (!descriptor.getCachePolicy().isSharedIsolation()){ Object cachedObject = null; if (this.identityMapManager != null){ cachedObject = getIdentityMapManager().getFromIdentityMap(primaryKey, theClass, shouldReturnInvalidatedObjects, descriptor); } if (descriptor.getCachePolicy().isIsolated()) { return cachedObject; }else{ return getAndCloneCacheKeyFromParent(primaryKey, object, theClass, shouldReturnInvalidatedObjects, descriptor); } } else { return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, object, theClass, shouldReturnInvalidatedObjects, descriptor); } }
/** * ADVANCED: * Return the object from the identity with the primary and class. */ @Override public Object getFromIdentityMap(Object primaryKey, Object object, Class theClass, boolean shouldReturnInvalidatedObjects, ClassDescriptor descriptor) { if (!descriptor.getCachePolicy().isSharedIsolation()){ Object cachedObject = null; if (this.identityMapManager != null){ cachedObject = getIdentityMapManager().getFromIdentityMap(primaryKey, theClass, shouldReturnInvalidatedObjects, descriptor); } if (descriptor.getCachePolicy().isIsolated()) { return cachedObject; }else{ return getAndCloneCacheKeyFromParent(primaryKey, object, theClass, shouldReturnInvalidatedObjects, descriptor); } } else { return ((IsolatedClientSession)session).getParent().getIdentityMapAccessorInstance().getFromIdentityMap(primaryKey, object, theClass, shouldReturnInvalidatedObjects, descriptor); } }
/** * 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: * Allow the inheritance properties of the descriptor to be initialized. * The descriptor's parent must first be initialized. */ public void initializeFromParent(CachePolicy parentPolicy, ClassDescriptor descriptor, ClassDescriptor descriptorDescriptor, AbstractSession session) throws DescriptorException { // If the parent is isolated, then the child must also be isolated. if (!parentPolicy.isSharedIsolation()) { // Do not override cache isolation when explicitly enabled by @Cacheable(true) annotation in current class. boolean copyParrent = cacheable == null || cacheable == false; if (!isIsolated() && (getCacheIsolation() != parentPolicy.getCacheIsolation()) && copyParrent) { session.log(SessionLog.WARNING, SessionLog.METADATA, "overriding_cache_isolation", new Object[]{descriptorDescriptor.getAlias(), parentPolicy.getCacheIsolation(), descriptor.getAlias(), getCacheIsolation()}); setCacheIsolation(parentPolicy.getCacheIsolation()); } } // Child must maintain the same indexes as the parent. for (CacheIndex index : parentPolicy.getCacheIndexes().values()) { addCacheIndex(index); } if ((getDatabaseChangeNotificationType() == null) && (parentPolicy.getDatabaseChangeNotificationType() != null)) { setDatabaseChangeNotificationType(parentPolicy.getDatabaseChangeNotificationType()); } if ((getCacheSynchronizationType() == UNDEFINED_OBJECT_CHANGE_BEHAVIOR) && (parentPolicy.getCacheSynchronizationType() != UNDEFINED_OBJECT_CHANGE_BEHAVIOR)) { setCacheSynchronizationType(parentPolicy.getCacheSynchronizationType()); } }