/**
   * INTERNAL: Return the classification for the field contained in the mapping. This is used to
   * convert the row value to a consistent java value.
   */
  @Override
  public Class getFieldClassification(DatabaseField fieldToClassify) {
    if ((getTypeField() != null) && (fieldToClassify.equals(getTypeField()))) {
      return getTypeField().getType();
    }

    String queryKey = (String) getSourceToTargetQueryKeyNames().get(fieldToClassify);
    if (queryKey == null) {
      return null;
    }
    // Search any of the implementor descriptors for a mapping for the query-key.
    Iterator iterator =
        getReferenceDescriptor().getInterfacePolicy().getChildDescriptors().iterator();
    if (iterator.hasNext()) {
      ClassDescriptor firstChild = (ClassDescriptor) iterator.next();
      DatabaseMapping mapping = firstChild.getObjectBuilder().getMappingForAttributeName(queryKey);
      if ((mapping != null) && (mapping.isDirectToFieldMapping())) {
        return ((AbstractDirectMapping) mapping).getAttributeClassification();
      }
      QueryKey targetQueryKey = firstChild.getQueryKeyNamed(queryKey);
      if ((targetQueryKey != null) && (targetQueryKey.isDirectQueryKey())) {
        return firstChild
            .getObjectBuilder()
            .getFieldClassification(((DirectQueryKey) targetQueryKey).getField());
      }
    }
    return null;
  }
  /** INTERNAL: Get a value from the object and set that in the respective field of the row. */
  @Override
  public Object valueFromObject(Object object, DatabaseField field, AbstractSession session) {
    // First check if the value can be obtained from the value holder's row.
    AbstractRecord referenceRow =
        getIndirectionPolicy().extractReferenceRow(getAttributeValueFromObject(object));
    if (referenceRow != null) {
      Object value = referenceRow.get(field);

      // Must ensure the classification to get a cache hit.
      try {
        value = session.getDatasourcePlatform().convertObject(value, getFieldClassification(field));
      } catch (ConversionException e) {
        throw ConversionException.couldNotBeConverted(this, getDescriptor(), e);
      }

      return value;
    }

    // 2.5.1.6 PWK.  added to support batch reading on variable one to ones
    Object referenceObject = getRealAttributeValueFromObject(object, session);
    String queryKeyName = (String) getSourceToTargetQueryKeyNames().get(field);
    ClassDescriptor objectDescriptor = session.getDescriptor(referenceObject.getClass());
    DatabaseField targetField =
        objectDescriptor.getObjectBuilder().getTargetFieldForQueryKeyName(queryKeyName);

    if (targetField == null) {
      return null;
    }

    return objectDescriptor
        .getObjectBuilder()
        .extractValueFromObjectForField(referenceObject, targetField, session);
  }
 public Object getObjectForUpdate(
     Session session,
     Object objectToUpdateBeforeChange,
     Object objectToUpdateAfterChange,
     boolean useUOW) {
   ClassDescriptor desc = session.getClassDescriptor(objectToUpdateBeforeChange);
   Record rowBeforeChange =
       desc.getObjectBuilder()
           .buildRow(objectToUpdateBeforeChange, (AbstractSession) session, WriteType.UPDATE);
   Record rowAfterChange =
       desc.getObjectBuilder()
           .buildRow(objectToUpdateAfterChange, (AbstractSession) session, WriteType.UPDATE);
   Record rowChange = new DatabaseRecord();
   getChange(
       rowChange,
       session,
       objectToUpdateBeforeChange,
       objectToUpdateAfterChange,
       desc,
       useUOW,
       WriteType.UPDATE);
   Record rowReturn = getRowForUpdate(rowChange);
   if (rowReturn != null && !rowReturn.isEmpty()) {
     Record row = new DatabaseRecord(rowAfterChange.size());
     row.putAll(rowAfterChange);
     row.putAll(rowReturn);
     return readObjectFromRow(session, desc, row);
   } else {
     return objectToUpdateAfterChange;
   }
 }
  /**
   * INTERNAL: Compare the references of the two objects are the same, not the objects themselves.
   * Used for independent relationships. This is used for testing and validation purposes.
   *
   * <p>Must get separate fields for the objects because we may be adding a different class to the
   * attribute because of the interface
   */
  @Override
  protected boolean compareObjectsWithoutPrivateOwned(
      Object firstObject, Object secondObject, AbstractSession session) {
    Object firstPrivateObject = getRealAttributeValueFromObject(firstObject, session);
    Object secondPrivateObject = getRealAttributeValueFromObject(secondObject, session);

    if ((firstPrivateObject == null) && (secondPrivateObject == null)) {
      return true;
    }

    if ((firstPrivateObject == null) || (secondPrivateObject == null)) {
      return false;
    }
    if (firstPrivateObject.getClass() != secondPrivateObject.getClass()) {
      return false;
    }
    Iterator targetKeys = getSourceToTargetQueryKeyNames().values().iterator();
    ClassDescriptor descriptor = session.getDescriptor(firstPrivateObject.getClass());
    ClassDescriptor descriptor2 = session.getDescriptor(secondPrivateObject.getClass());

    while (targetKeys.hasNext()) {
      String queryKey = (String) targetKeys.next();
      DatabaseField field = descriptor.getObjectBuilder().getFieldForQueryKeyName(queryKey);
      Object firstObjectField =
          descriptor
              .getObjectBuilder()
              .extractValueFromObjectForField(firstPrivateObject, field, session);
      DatabaseField field2 = descriptor2.getObjectBuilder().getFieldForQueryKeyName(queryKey);
      Object secondObjectField =
          descriptor2
              .getObjectBuilder()
              .extractValueFromObjectForField(secondPrivateObject, field2, session);

      if (!((firstObjectField == null) && (secondObjectField == null))) {
        if ((firstObjectField == null) || (secondObjectField == null)) {
          return false;
        }
        if (!firstObjectField.equals(secondObjectField)) {
          return false;
        }
      }
    }

    return true;
  }
 @Override
 protected Object buildCompositeObject(
     ClassDescriptor descriptor,
     AbstractRecord nestedRow,
     ObjectBuildingQuery query,
     CacheKey parentCacheKey,
     JoinedAttributeManager joinManger,
     AbstractSession targetSession) {
   return descriptor.getObjectBuilder().buildObject(query, nestedRow, joinManger);
 }
 @Override
 protected Object buildCompositeObject(
     ClassDescriptor descriptor,
     AbstractRecord nestedRow,
     ObjectBuildingQuery query,
     CacheKey parentsCacheKey,
     JoinedAttributeManager joinManager,
     AbstractSession targetSession) {
   if (((EISDescriptor) descriptor).getDataFormat() == EISDescriptor.XML) {
     return descriptor.getObjectBuilder().buildObject(query, nestedRow, joinManager);
   } else {
     Object element = descriptor.getObjectBuilder().buildNewInstance();
     descriptor
         .getObjectBuilder()
         .buildAttributesIntoObject(
             element, parentsCacheKey, nestedRow, query, joinManager, false, targetSession);
     return element;
   }
 }
  /** INTERNAL: Get a value from the object and set that in the respective field of the row. */
  @Override
  public void writeFromObjectIntoRowForWhereClause(
      ObjectLevelModifyQuery query, AbstractRecord record) {
    if (isReadOnly()) {
      return;
    }
    Object object;
    if (query.isDeleteObjectQuery()) {
      object = query.getObject();
    } else {
      object = query.getBackupClone();
    }
    Object referenceObject = getRealAttributeValueFromObject(object, query.getSession());

    if (referenceObject == null) {
      writeFromNullObjectIntoRow(record);
    } else {
      if (isForeignKeyRelationship()) {
        Enumeration sourceFields = getForeignKeyFields().elements();
        ClassDescriptor descriptor = query.getSession().getDescriptor(referenceObject.getClass());
        while (sourceFields.hasMoreElements()) {
          DatabaseField sourceKey = (DatabaseField) sourceFields.nextElement();
          String targetQueryKey = (String) getSourceToTargetQueryKeyNames().get(sourceKey);
          DatabaseField targetKeyField =
              descriptor.getObjectBuilder().getFieldForQueryKeyName(targetQueryKey);
          if (targetKeyField == null) {
            throw DescriptorException.variableOneToOneMappingIsNotDefinedProperly(
                this, descriptor, targetQueryKey);
          }
          Object referenceValue =
              descriptor
                  .getObjectBuilder()
                  .extractValueFromObjectForField(
                      referenceObject, targetKeyField, query.getSession());
          record.put(sourceKey, referenceValue);
        }
      }
      if (getTypeField() != null) {
        record.put(getTypeField(), getTypeForImplementor(referenceObject.getClass()));
      }
    }
  }
 @Override
 protected Object buildCompositeObject(
     ClassDescriptor descriptor,
     AbstractRecord nestedRow,
     ObjectBuildingQuery query,
     CacheKey parentCacheKey,
     JoinedAttributeManager joinManager,
     AbstractSession targetSession) {
   Object element = descriptor.getObjectBuilder().buildNewInstance();
   descriptor
       .getObjectBuilder()
       .buildAttributesIntoObject(
           element,
           parentCacheKey,
           nestedRow,
           query,
           joinManager,
           query.getExecutionFetchGroup(descriptor),
           false,
           targetSession);
   return element;
 }
 /**
  * INTERNAL: Retrieve the target object's primary key value that is mapped to a given source xpath
  * (in the source-target key field association list).
  *
  * @param targetObject - the reference class instance that holds the required pk value
  * @param xmlFld
  * @param session
  * @return null if the target object is null, the reference class is null, or a primary key field
  *     name does not exist on the reference descriptor that matches the target field name -
  *     otherwise, return the associated primary key value
  */
 public Object buildFieldValue(Object targetObject, XMLField xmlFld, AbstractSession session) {
   if (targetObject == null || getReferenceClass() == null) {
     return null;
   }
   ClassDescriptor descriptor = getReferenceDescriptor();
   ObjectBuilder objectBuilder = descriptor.getObjectBuilder();
   Vector pks = objectBuilder.extractPrimaryKeyFromObject(targetObject, session);
   XMLField tgtXMLField = (XMLField) getSourceToTargetKeyFieldAssociations().get(xmlFld);
   int idx = descriptor.getPrimaryKeyFields().indexOf(tgtXMLField);
   if (idx == -1) {
     return null;
   }
   return pks.get(idx);
 }
  /**
   * INTERNAL: Get a value from the object and set that in the respective field of the row. If the
   * mapping id target foreign key, you must only write the type into the roe, the rest will be
   * updated when the object itself is written
   */
  @Override
  public void writeFromObjectIntoRowWithChangeRecord(
      ChangeRecord changeRecord, AbstractRecord record, AbstractSession session) {
    if (isReadOnly()) {
      return;
    }

    ObjectChangeSet changeSet =
        (ObjectChangeSet) ((ObjectReferenceChangeRecord) changeRecord).getNewValue();
    if (changeSet == null) {
      writeFromNullObjectIntoRow(record);
    } else {
      Object referenceObject = changeSet.getUnitOfWorkClone();
      if (isForeignKeyRelationship()) {
        Enumeration sourceFields = getForeignKeyFields().elements();
        ClassDescriptor descriptor = session.getDescriptor(referenceObject.getClass());
        while (sourceFields.hasMoreElements()) {
          DatabaseField sourceKey = (DatabaseField) sourceFields.nextElement();
          String targetQueryKey = (String) getSourceToTargetQueryKeyNames().get(sourceKey);
          DatabaseField targetKeyField =
              descriptor.getObjectBuilder().getFieldForQueryKeyName(targetQueryKey);
          if (targetKeyField == null) {
            throw DescriptorException.variableOneToOneMappingIsNotDefinedProperly(
                this, descriptor, targetQueryKey);
          }
          Object referenceValue =
              descriptor
                  .getObjectBuilder()
                  .extractValueFromObjectForField(referenceObject, targetKeyField, session);
          record.put(sourceKey, referenceValue);
        }
      }
      if (getTypeField() != null) {
        record.put(getTypeField(), getTypeForImplementor(referenceObject.getClass()));
      }
    }
  }
  /**
   * INTERNAL: This method marks the object as changed. This method is only called by EclipseLink
   */
  public void internalPropertyChange(PropertyChangeEvent evt) {
    if (evt.getNewValue() == evt.getOldValue()) {
      return;
    }

    DatabaseMapping mapping =
        descriptor.getObjectBuilder().getMappingForAttributeName(evt.getPropertyName());
    // Bug#4127952 Throw an exception indicating there is no mapping for the property name.
    if (mapping == null) {
      throw ValidationException.wrongPropertyNameInChangeEvent(
          owner.getClass(), evt.getPropertyName());
    }
    if (mapping instanceof AbstractDirectMapping
        || mapping instanceof AbstractTransformationMapping) {
      // If both newValue and oldValue are null, or newValue is not null and newValue equals
      // oldValue, don't build ChangeRecord
      if (((evt.getNewValue() == null) && (evt.getOldValue() == null))
          || ((evt.getNewValue() != null) && (evt.getNewValue()).equals(evt.getOldValue()))) {
        return;
      }
    }

    super.internalPropertyChange(evt);

    if (uow.getUnitOfWorkChangeSet() == null) {
      uow.setUnitOfWorkChangeSet(new UnitOfWorkChangeSet(uow));
    }
    if (objectChangeSet == null) { // only null if new or if in a new UOW
      // add to tracker list to prevent GC of clone if using weak references
      // put it in here so that it only occurs on the 1st change for a particular UOW
      uow.addToChangeTrackedHardList(owner);
      objectChangeSet =
          getDescriptor()
              .getObjectBuilder()
              .createObjectChangeSet(
                  owner, (UnitOfWorkChangeSet) uow.getUnitOfWorkChangeSet(), false, uow);
    }

    if (evt.getClass().equals(ClassConstants.PropertyChangeEvent_Class)) {
      mapping.updateChangeRecord(
          evt.getSource(), evt.getNewValue(), evt.getOldValue(), objectChangeSet, getUnitOfWork());
    } else if (evt.getClass().equals(ClassConstants.CollectionChangeEvent_Class)
        || (evt.getClass().equals(ClassConstants.MapChangeEvent_Class))) {
      mapping.updateCollectionChangeRecord(
          (CollectionChangeEvent) evt, objectChangeSet, getUnitOfWork());
    } else {
      throw ValidationException.wrongChangeEvent(evt.getClass());
    }
  }
예제 #12
0
 // bug 331064 - Sort the delete order based on PKs.
 private List sort(Class theClass, List objects) {
   ClassDescriptor descriptor = session.getDescriptor(theClass);
   org.eclipse.persistence.internal.descriptors.ObjectBuilder objectBuilder =
       descriptor.getObjectBuilder();
   int size = objects.size();
   TreeMap sortedObjects = new TreeMap();
   for (int index = 0; index < size; index++) {
     Object objectToDelete = objects.get(index);
     if (objectToDelete.getClass() == theClass) {
       sortedObjects.put(
           objectBuilder.extractPrimaryKeyFromObject(objectToDelete, session), objectToDelete);
     }
   }
   return new ArrayList(sortedObjects.values());
 }
 public Object getObjectForInsert(Session session, Object objectToInsert) {
   ClassDescriptor desc = session.getClassDescriptor(objectToInsert);
   Record rowToInsert =
       desc.getObjectBuilder()
           .buildRow(objectToInsert, (AbstractSession) session, WriteType.INSERT);
   Record rowReturn = getRowForInsert(rowToInsert);
   if (rowReturn != null && !rowReturn.isEmpty()) {
     Record row = new DatabaseRecord(rowToInsert.size());
     row.putAll(rowToInsert);
     row.putAll(rowReturn);
     return readObjectFromRow(session, desc, row);
   } else {
     return objectToInsert;
   }
 }
  protected AbstractRecord buildCompositeRowForDescriptor(
      ClassDescriptor classDesc,
      Object attributeValue,
      AbstractSession session,
      XMLRecord parentRow,
      WriteType writeType) {
    XMLObjectBuilder objectBuilder = (XMLObjectBuilder) classDesc.getObjectBuilder();

    XMLRecord child =
        (XMLRecord)
            objectBuilder.createRecordFor(attributeValue, (XMLField) getField(), parentRow, this);
    child.setNamespaceResolver(parentRow.getNamespaceResolver());
    child.setSession(session);
    objectBuilder.buildIntoNestedRow(
        child,
        attributeValue,
        session,
        (XMLDescriptor) getReferenceDescriptor(),
        (XMLField) getField());
    return child;
  }
 protected Object readObjectFromRow(Session session, ClassDescriptor desc, Record row) {
   if (desc.hasInheritance()) {
     Class newClass =
         desc.getInheritancePolicy().classFromRow((DatabaseRecord) row, (AbstractSession) session);
     desc = session.getClassDescriptor(newClass);
   }
   Object object = desc.getObjectBuilder().buildNewInstance();
   ReadObjectQuery query = new ReadObjectQuery();
   query.setSession((AbstractSession) session);
   for (Enumeration mappings = desc.getMappings().elements(); mappings.hasMoreElements(); ) {
     DatabaseMapping mapping = (DatabaseMapping) mappings.nextElement();
     mapping.readFromRowIntoObject(
         (DatabaseRecord) row,
         query.getJoinedAttributeManager(),
         object,
         null,
         query,
         query.getSession(),
         true);
   }
   return object;
 }
  protected boolean compare(int i) {
    if (objectVectors[i] == null) {
      return false;
    }
    Vector currentVector = getDbSession().readAllObjects(classes[i]);

    if (currentVector.size() != objectVectors[i].size()) {
      return false;
    }
    ClassDescriptor descriptor = getDbSession().getDescriptor(classes[i]);
    for (int j = 0; j < currentVector.size(); j++) {
      Object obj1 = objectVectors[i].elementAt(j);
      Object obj2 = currentVector.elementAt(j);
      if (!descriptor
          .getObjectBuilder()
          .compareObjects(
              obj1,
              obj2,
              (org.eclipse.persistence.internal.sessions.AbstractSession) getDbSession())) {
        return false;
      }
    }
    return true;
  }
 /** @return DatabaseMapping for given attribute name */
 private DatabaseMapping getMappingForAttributeName(String attributeName) {
   return descriptor.getObjectBuilder().getMappingForAttributeName(attributeName);
 }
예제 #18
0
  /**
   * INTERNAL: Check if existence can be determined without going to the database. Note that custom
   * query check is not require for does exist as the custom is always used. Used by unit of work,
   * and will return null if checkDatabaseIfInvalid is set and the cachekey is invalidated
   */
  public Object checkEarlyReturn(
      Object object, Vector primaryKey, AbstractSession session, AbstractRecord translationRow) {
    // For bug 3136413/2610803 building the selection criteria from an EJBQL string or
    // an example object is done just in time.
    buildSelectionCriteria(session);
    // Return false on null since it can't exist.  Little more done in case PK not set in the query
    if (object == null) {
      return Boolean.FALSE;
    }
    ClassDescriptor descriptor = session.getDescriptor(object.getClass());
    if (primaryKey == null) {
      primaryKey = getPrimaryKey();
      if (primaryKey == null) {
        primaryKey =
            descriptor.getObjectBuilder().extractPrimaryKeyFromObject(object, session, true);
      }
    }
    if ((primaryKey == null) || (primaryKey.contains(null))) {
      return Boolean.FALSE;
    }

    // Need to do the cache check first if flag set or if we should check the cache only for
    // existence.
    if ((shouldCheckCacheForDoesExist() || this.checkCacheFirst)
        && !descriptor.isDescriptorForInterface()) {

      // If this is a UOW and modification queries have been executed, the cache cannot be trusted.
      if (this.checkDatabaseIfInvalid
          && (session.isUnitOfWork() && ((UnitOfWorkImpl) session).shouldReadFromDB())) {
        return null;
      }

      CacheKey cacheKey;
      Class objectClass = object.getClass();
      AbstractSession tempSession = session;
      while (tempSession.isUnitOfWork()) { // could be nested lets check all UOWs
        cacheKey =
            tempSession
                .getIdentityMapAccessorInstance()
                .getCacheKeyForObjectForLock(primaryKey, objectClass, descriptor);
        if (cacheKey != null) {
          // If in the UOW cache it can't be invalid.
          return Boolean.TRUE;
        }
        tempSession = ((UnitOfWorkImpl) tempSession).getParent();
      }
      // Did not find it registered in UOW so check main cache and check for invalidation.
      cacheKey =
          tempSession
              .getIdentityMapAccessorInstance()
              .getCacheKeyForObject(primaryKey, objectClass, descriptor);

      if ((cacheKey != null)) {
        // Assume that if there is a cachekey, object exists.
        if (this.checkDatabaseIfInvalid) {
          checkDescriptor(object, session);
          if (this.descriptor
              .getCacheInvalidationPolicy()
              .isInvalidated(cacheKey, System.currentTimeMillis())) {
            return null;
          }
        }

        Object objectFromCache = cacheKey.getObject();
        if ((session.isUnitOfWork()) && ((UnitOfWorkImpl) session).wasDeleted(objectFromCache)) {
          if (shouldCheckCacheForDoesExist()) {
            return Boolean.FALSE;
          }
        } else {
          return Boolean.TRUE;
        }
      } else if (shouldCheckCacheForDoesExist()) {
        // We know its not in cache, and a checkcache policy so return false.
        return Boolean.FALSE;
      }
    }
    // Check if we have to assume that the object does not exist.
    if (shouldAssumeNonExistenceForDoesExist()) {
      return Boolean.FALSE;
    }

    // Check to see if we only need to check that the object contains a primary key.
    if (shouldAssumeExistenceForDoesExist()) {
      return Boolean.TRUE;
    }

    return null;
  }
  /**
   * INTERNAL: Build and return the nested rows from the specified field value. This method allows
   * the field value to be an ARRAY containing other structures such as arrays or Struct, or direct
   * values.
   */
  public static Object buildContainerFromArray(
      Array fieldValue, ObjectRelationalDatabaseField arrayField, AbstractSession session)
      throws DatabaseException {
    if (arrayField.getType() == null) {
      return fieldValue;
    }
    Object[] objects = null;
    try {
      objects = (Object[]) fieldValue.getArray();
    } catch (java.sql.SQLException ex) {
      throw DatabaseException.sqlException(ex, session, false);
    }
    if (objects == null) {
      return null;
    }

    boolean isNestedStructure = false;
    ObjectRelationalDataTypeDescriptor ord = null;
    DatabaseField nestedType = null;
    if (arrayField != null) {
      nestedType = arrayField.getNestedTypeField();
      if ((nestedType != null) && nestedType.getSqlType() == Types.STRUCT) {
        ClassDescriptor descriptor = session.getDescriptor(nestedType.getType());
        if ((descriptor != null) && (descriptor.isObjectRelationalDataTypeDescriptor())) {
          // this is used to convert non-null objects passed through stored procedures and custom
          // SQL to structs
          ord = (ObjectRelationalDataTypeDescriptor) descriptor;
        }
      } else if ((nestedType != null) && (nestedType instanceof ObjectRelationalDatabaseField)) {
        isNestedStructure = true;
      }
    }
    // handle ARRAY conversions
    ReadObjectQuery query = new ReadObjectQuery();
    query.setSession(session);
    ContainerPolicy cp = ContainerPolicy.buildPolicyFor(arrayField.getType());
    Object container = cp.containerInstance(objects.length);
    for (int i = 0; i < objects.length; i++) {
      Object arrayValue = objects[i];
      if (arrayValue == null) {
        return null;
      }
      if (ord != null) {
        AbstractRecord nestedRow = ord.buildRowFromStructure((Struct) arrayValue);
        ClassDescriptor descriptor = ord;
        if (descriptor.hasInheritance()) {
          Class newElementClass =
              descriptor.getInheritancePolicy().classFromRow(nestedRow, session);
          if (!descriptor.getJavaClass().equals(newElementClass)) {
            descriptor = session.getDescriptor(newElementClass);
            if (descriptor == null) {
              descriptor = ord;
            }
          }
        }
        arrayValue = descriptor.getObjectBuilder().buildNewInstance();
        descriptor
            .getObjectBuilder()
            .buildAttributesIntoObject(arrayValue, nestedRow, query, null, false);
      } else if (isNestedStructure && (arrayValue instanceof Array)) {
        arrayValue =
            buildContainerFromArray(
                (Array) arrayValue, (ObjectRelationalDatabaseField) nestedType, session);
      }

      cp.addInto(arrayValue, container, session);
    }
    return container;
  }