Program: 64027
Project: 64027
Buggy source:
/** 
 * INTERNAL: Builds a working copy clone directly from the database row. This is the key method that allows us to execute queries against a UnitOfWork while in transaction and not cache the results in the shared cache.  This is because we might violate transaction isolation by putting uncommitted versions of objects in the shared cache.
 */
protected Object buildWorkingCopyCloneFromRow(ObjectBuildingQuery query,JoinedAttributeManager joinManager,AbstractRecord databaseRow,UnitOfWorkImpl unitOfWork,Object primaryKey,CacheKey preFetchedCacheKey) throws DatabaseException, QueryException {
  ClassDescriptor descriptor=this.descriptor;
  CacheKey unitOfWorkCacheKey=unitOfWork.getIdentityMapAccessorInstance().getIdentityMapManager().acquireLock(primaryKey,descriptor.getJavaClass(),false,descriptor,true);
  Object workingClone=unitOfWorkCacheKey.getObject();
  FetchGroup fetchGroup=query.getExecutionFetchGroup(descriptor);
  FetchGroupManager fetchGroupManager=descriptor.getFetchGroupManager();
  boolean hasSetSopObjectIntoRow=false;
  try {
    boolean wasAClone=workingClone != null;
    boolean isARefresh=query.shouldRefreshIdentityMapResult() || (query.isLockQuery() && (!wasAClone || !query.isClonePessimisticLocked(workingClone,unitOfWork)));
    if (wasAClone && fetchGroupManager != null && (fetchGroupManager.isPartialObject(workingClone) && (!fetchGroupManager.isObjectValidForFetchGroup(workingClone,fetchGroupManager.getEntityFetchGroup(fetchGroup))))) {
      isARefresh=true;
    }
    if (wasAClone && (!isARefresh)) {
      return workingClone;
    }
    boolean wasAnOriginal=false;
    boolean isIsolated=descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() || (descriptor.shouldIsolateObjectsInUnitOfWorkEarlyTransaction() && unitOfWork.wasTransactionBegunPrematurely());
    Object original=null;
    CacheKey originalCacheKey=null;
    if ((!isARefresh) && (!isIsolated) && !query.shouldRetrieveBypassCache()&& !unitOfWork.shouldReadFromDB()&& (!unitOfWork.shouldForceReadFromDB(query,primaryKey))) {
      AbstractSession session=unitOfWork.getParentIdentityMapSession(query);
      if (preFetchedCacheKey == null) {
        originalCacheKey=session.getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey,descriptor.getJavaClass(),descriptor,false);
      }
 else {
        originalCacheKey=preFetchedCacheKey;
        originalCacheKey.acquireLock(query);
      }
      if (originalCacheKey != null) {
        original=originalCacheKey.getObject();
        wasAnOriginal=original != null;
        isARefresh=wasAnOriginal && (descriptor.shouldAlwaysRefreshCache() || descriptor.getCacheInvalidationPolicy().isInvalidated(originalCacheKey,query.getExecutionTime()));
        if (wasAnOriginal && (!isARefresh)) {
          if (descriptor.getCachePolicy().isSharedIsolation() || !descriptor.shouldIsolateProtectedObjectsInUnitOfWork()) {
            return unitOfWork.cloneAndRegisterObject(original,originalCacheKey,unitOfWorkCacheKey,descriptor);
          }
        }
      }
    }
    if (!wasAClone) {
      if (wasAnOriginal && !query.shouldRetrieveBypassCache()) {
        workingClone=instantiateWorkingCopyClone(original,unitOfWork);
        unitOfWork.getCloneToOriginals().put(workingClone,original);
      }
 else {
        if (query.shouldUseSerializedObjectPolicy() && descriptor.hasSerializedObjectPolicy() && !databaseRow.hasSopObject()) {
          hasSetSopObjectIntoRow=true;
          workingClone=descriptor.getSerializedObjectPolicy().getObjectFromRow(databaseRow,unitOfWork);
        }
        if (workingClone == null) {
          workingClone=buildNewInstance();
        }
      }
      unitOfWorkCacheKey.setObject(workingClone);
      unitOfWork.getCloneMapping().put(workingClone,workingClone);
    }
    if (wasAClone && (unitOfWorkCacheKey.getLastUpdatedQueryId() >= query.getQueryId())) {
      return workingClone;
    }
    copyQueryInfoToCacheKey(unitOfWorkCacheKey,query,databaseRow,unitOfWork,descriptor);
    ObjectChangePolicy policy=descriptor.getObjectChangePolicy();
    if (!wasAClone) {
      policy.setChangeListener(workingClone,unitOfWork,descriptor);
    }
    policy.dissableEventProcessing(workingClone);
    if (isARefresh && fetchGroupManager != null) {
      fetchGroupManager.setObjectFetchGroup(workingClone,query.getExecutionFetchGroup(this.descriptor),unitOfWork);
    }
    if (descriptor.getCachePolicy().isProtectedIsolation() && !isIsolated && !query.shouldStoreBypassCache()) {
      originalCacheKey=(CacheKey)buildObject(true,query,databaseRow,unitOfWork.getParentIdentityMapSession(descriptor,false,true),primaryKey,preFetchedCacheKey,descriptor,joinManager);
    }
    if (isARefresh) {
      originalCacheKey=null;
    }
    buildAttributesIntoWorkingCopyClone(workingClone,originalCacheKey,query,joinManager,databaseRow,unitOfWork,wasAClone);
    if ((!isARefresh) && fetchGroupManager != null) {
      fetchGroupManager.setObjectFetchGroup(workingClone,query.getExecutionFetchGroup(this.descriptor),unitOfWork);
    }
    Object backupClone=policy.buildBackupClone(workingClone,this,unitOfWork);
    if (wasAClone) {
      policy.clearChanges(workingClone,unitOfWork,descriptor,isARefresh);
    }
    policy.enableEventProcessing(workingClone);
    unitOfWork.getCloneMapping().put(workingClone,backupClone);
    query.recordCloneForPessimisticLocking(workingClone,unitOfWork);
    if (workingClone instanceof PersistenceEntity) {
      ((PersistenceEntity)workingClone)._persistence_setId(primaryKey);
    }
  }
  finally {
    unitOfWorkCacheKey.release();
    if (hasSetSopObjectIntoRow) {
      databaseRow.setSopObject(null);
    }
  }
  instantiateEagerMappings(workingClone,unitOfWork);
  return workingClone;
}

Fixed version (ground truth):
/** 
 * INTERNAL: Builds a working copy clone directly from the database row. This is the key method that allows us to execute queries against a UnitOfWork while in transaction and not cache the results in the shared cache.  This is because we might violate transaction isolation by putting uncommitted versions of objects in the shared cache.
 */
protected Object buildWorkingCopyCloneFromRow(ObjectBuildingQuery query,JoinedAttributeManager joinManager,AbstractRecord databaseRow,UnitOfWorkImpl unitOfWork,Object primaryKey,CacheKey preFetchedCacheKey) throws DatabaseException, QueryException {
  ClassDescriptor descriptor=this.descriptor;
  CacheKey unitOfWorkCacheKey=unitOfWork.getIdentityMapAccessorInstance().getIdentityMapManager().acquireLock(primaryKey,descriptor.getJavaClass(),false,descriptor,true);
  Object workingClone=unitOfWorkCacheKey.getObject();
  FetchGroup fetchGroup=query.getExecutionFetchGroup(descriptor);
  FetchGroupManager fetchGroupManager=descriptor.getFetchGroupManager();
  boolean hasSetSopObjectIntoRow=false;
  try {
    boolean wasAClone=workingClone != null;
    boolean isARefresh=query.shouldRefreshIdentityMapResult() || (query.isLockQuery() && (!wasAClone || !query.isClonePessimisticLocked(workingClone,unitOfWork)));
    if (wasAClone && fetchGroupManager != null && (fetchGroupManager.isPartialObject(workingClone) && (!fetchGroupManager.isObjectValidForFetchGroup(workingClone,fetchGroupManager.getEntityFetchGroup(fetchGroup))))) {
      isARefresh=true;
    }
    if (wasAClone && (!isARefresh)) {
      return workingClone;
    }
    boolean wasAnOriginal=false;
    boolean isIsolated=descriptor.getCachePolicy().shouldIsolateObjectsInUnitOfWork() || (descriptor.shouldIsolateObjectsInUnitOfWorkEarlyTransaction() && unitOfWork.wasTransactionBegunPrematurely());
    Object original=null;
    CacheKey originalCacheKey=null;
    if ((!isARefresh) && (!isIsolated) && !query.shouldRetrieveBypassCache()&& !unitOfWork.shouldReadFromDB()&& (!unitOfWork.shouldForceReadFromDB(query,primaryKey))) {
      AbstractSession session=unitOfWork.getParentIdentityMapSession(query);
      if (preFetchedCacheKey == null) {
        originalCacheKey=session.getIdentityMapAccessorInstance().getCacheKeyForObject(primaryKey,descriptor.getJavaClass(),descriptor,false);
      }
 else {
        originalCacheKey=preFetchedCacheKey;
        originalCacheKey.acquireLock(query);
      }
      if (originalCacheKey != null) {
        original=originalCacheKey.getObject();
        wasAnOriginal=original != null;
        isARefresh=wasAnOriginal && (descriptor.shouldAlwaysRefreshCache() || descriptor.getCacheInvalidationPolicy().isInvalidated(originalCacheKey,query.getExecutionTime()));
        if (wasAnOriginal && (!isARefresh)) {
          if (descriptor.getCachePolicy().isSharedIsolation() || !descriptor.shouldIsolateProtectedObjectsInUnitOfWork()) {
            return unitOfWork.cloneAndRegisterObject(original,originalCacheKey,unitOfWorkCacheKey,descriptor);
          }
        }
      }
    }
    if (!wasAClone) {
      if (wasAnOriginal && !query.shouldRetrieveBypassCache()) {
        workingClone=instantiateWorkingCopyClone(original,unitOfWork);
        unitOfWork.getCloneToOriginals().put(workingClone,original);
      }
 else {
        if (query.shouldUseSerializedObjectPolicy() && descriptor.hasSerializedObjectPolicy() && !databaseRow.hasSopObject()) {
          hasSetSopObjectIntoRow=true;
          workingClone=descriptor.getSerializedObjectPolicy().getObjectFromRow(databaseRow,unitOfWork);
        }
        if (workingClone == null) {
          workingClone=buildNewInstance();
        }
      }
      unitOfWorkCacheKey.setObject(workingClone);
      unitOfWork.getCloneMapping().put(workingClone,workingClone);
    }
    if (wasAClone && (unitOfWorkCacheKey.getLastUpdatedQueryId() >= query.getQueryId())) {
      return workingClone;
    }
    copyQueryInfoToCacheKey(unitOfWorkCacheKey,query,databaseRow,unitOfWork,descriptor);
    ObjectChangePolicy policy=descriptor.getObjectChangePolicy();
    if (!wasAClone) {
      policy.setChangeListener(workingClone,unitOfWork,descriptor);
    }
    policy.dissableEventProcessing(workingClone);
    if (isARefresh && fetchGroupManager != null) {
      fetchGroupManager.setObjectFetchGroup(workingClone,query.getExecutionFetchGroup(this.descriptor),unitOfWork);
    }
    if (!unitOfWork.wasTransactionBegunPrematurely() && descriptor.getCachePolicy().isProtectedIsolation() && !isIsolated&& !query.shouldStoreBypassCache()) {
      originalCacheKey=(CacheKey)buildObject(true,query,databaseRow,unitOfWork.getParentIdentityMapSession(descriptor,false,true),primaryKey,preFetchedCacheKey,descriptor,joinManager);
    }
    if (isARefresh) {
      originalCacheKey=null;
    }
    buildAttributesIntoWorkingCopyClone(workingClone,originalCacheKey,query,joinManager,databaseRow,unitOfWork,wasAClone);
    if ((!isARefresh) && fetchGroupManager != null) {
      fetchGroupManager.setObjectFetchGroup(workingClone,query.getExecutionFetchGroup(this.descriptor),unitOfWork);
    }
    Object backupClone=policy.buildBackupClone(workingClone,this,unitOfWork);
    if (wasAClone) {
      policy.clearChanges(workingClone,unitOfWork,descriptor,isARefresh);
    }
    policy.enableEventProcessing(workingClone);
    unitOfWork.getCloneMapping().put(workingClone,backupClone);
    query.recordCloneForPessimisticLocking(workingClone,unitOfWork);
    if (workingClone instanceof PersistenceEntity) {
      ((PersistenceEntity)workingClone)._persistence_setId(primaryKey);
    }
  }
  finally {
    unitOfWorkCacheKey.release();
    if (hasSetSopObjectIntoRow) {
      databaseRow.setSopObject(null);
    }
  }
  instantiateEagerMappings(workingClone,unitOfWork);
  return workingClone;
}