/** * Convenience method to retrieve field values from an L2 cached object if they are loaded in that * object. If the object is not in the L2 cache then just returns, and similarly if the required * fields aren't available. * * @param fieldNumbers Numbers of fields to load from the L2 cache * @return The fields that couldn't be loaded */ protected int[] loadFieldsFromLevel2Cache(int[] fieldNumbers) { // Only continue if there are fields, and not being deleted/flushed etc if (fieldNumbers == null || fieldNumbers.length == 0 || myEC.isFlushing() || myLC.isDeleted() || isDeleting() || getExecutionContext().getTransaction().isCommitting()) { return fieldNumbers; } // TODO Drop this check when we're confident that this doesn't affect some use-cases if (!myEC.getNucleusContext() .getConfiguration() .getBooleanProperty(PropertyNames.PROPERTY_CACHE_L2_LOADFIELDS, true)) { return fieldNumbers; } Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache(); if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd)) { CachedPC<T> cachedPC = l2cache.get(myID); if (cachedPC != null) { int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, true); if (cacheFieldsToLoad != null && cacheFieldsToLoad.length > 0) { if (NucleusLogger.CACHE.isDebugEnabled()) { NucleusLogger.CACHE.debug( Localiser.msg( "026034", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad))); } L2CacheRetrieveFieldManager l2RetFM = new L2CacheRetrieveFieldManager(this, cachedPC); this.replaceFields(cacheFieldsToLoad, l2RetFM); int[] fieldsNotLoaded = l2RetFM.getFieldsNotLoaded(); if (fieldsNotLoaded != null) { for (int i = 0; i < fieldsNotLoaded.length; i++) { loadedFields[fieldsNotLoaded[i]] = false; } } } } } return ClassUtils.getFlagsSetTo(loadedFields, fieldNumbers, false); }
/** * Convenience method to update a Level2 cached version of this object if cacheable and has not * been modified during this transaction. * * @param fieldNumbers Numbers of fields to update in L2 cached object */ protected void updateLevel2CacheForFields(int[] fieldNumbers) { String updateMode = (String) myEC.getProperty(PropertyNames.PROPERTY_CACHE_L2_UPDATE_MODE); if (updateMode != null && updateMode.equalsIgnoreCase("commit-only")) { return; } if (fieldNumbers == null || fieldNumbers.length == 0) { return; } Level2Cache l2cache = myEC.getNucleusContext().getLevel2Cache(); if (l2cache != null && myEC.getNucleusContext().isClassCacheable(cmd) && !myEC.isObjectModifiedInTransaction(myID)) { CachedPC<T> cachedPC = l2cache.get(myID); if (cachedPC != null) { // This originally just updated the L2 cache for fields where the L2 cache didn't have a // value for that field, like this /* int[] cacheFieldsToLoad = ClassUtils.getFlagsSetTo(cachedPC.getLoadedFields(), fieldNumbers, false); if (cacheFieldsToLoad == null || cacheFieldsToLoad.length == 0) { return; } */ int[] cacheFieldsToLoad = fieldNumbers; CachedPC copyCachedPC = cachedPC.getCopy(); if (NucleusLogger.CACHE.isDebugEnabled()) { NucleusLogger.CACHE.debug( Localiser.msg( "026033", StringUtils.toJVMIDString(getObject()), myID, StringUtils.intArrayToString(cacheFieldsToLoad))); } provideFields(cacheFieldsToLoad, new L2CachePopulateFieldManager(this, copyCachedPC)); // Replace the current L2 cached object with this one myEC.getNucleusContext().getLevel2Cache().put(getInternalObjectId(), copyCachedPC); } } }