/** INTERNAL: Write fields needed for insert into the template for with null values. */
 public void writeInsertFieldsIntoRow(AbstractRecord row, AbstractSession session) {
   if (isForeignKeyRelationship() && !isReadOnly()) {
     if (getForeignKeyGroupingElement() != null) {
       row.put(getForeignKeyGroupingElement(), null);
     } else if (this.getSourceForeignKeyFields().size() > 0) {
       row.put(getSourceForeignKeyFields().get(0), null);
     }
   } else {
     super.writeInsertFieldsIntoRow(row, session);
   }
 }
  /**
   * INTERNAL: Get the appropriate attribute value from the object and put it in the appropriate
   * field of the database row. Loop through the reference objects and extract the primary keys and
   * put them in the vector of "nested" rows.
   */
  public void writeFromObjectIntoRow(Object object, AbstractRecord row, AbstractSession session) {
    if (!isForeignKeyRelationship) {
      return;
    }

    if (((getSourceForeignKeysToTargetKeys()) == null)
        || (getSourceForeignKeysToTargetKeys().size() == 0)) {
      return;
    }

    if (this.isReadOnly()) {
      return;
    }

    AbstractRecord referenceRow =
        this.getIndirectionPolicy().extractReferenceRow(this.getAttributeValueFromObject(object));
    if (referenceRow != null) {
      // the reference objects have not been instantiated - use the value from the original row
      if (getForeignKeyGroupingElement() != null) {
        row.put(
            this.getForeignKeyGroupingElement(),
            referenceRow.getValues(this.getForeignKeyGroupingElement()));
      } else if (getSourceForeignKeyFields().size() > 0) {
        DatabaseField foreignKeyField = (DatabaseField) getSourceForeignKeyFields().get(0);
        row.put(foreignKeyField, referenceRow.getValues(foreignKeyField));
      }
      return;
    }

    ContainerPolicy cp = this.getContainerPolicy();

    // extract the keys from the objects
    Object attributeValue = this.getRealCollectionAttributeValueFromObject(object, session);
    Vector nestedRows = new Vector(cp.sizeFor(attributeValue));

    if (getForeignKeyGroupingElement() != null) {
      for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter); ) {
        XMLRecord nestedRow =
            this.extractKeyRowFromReferenceObject(cp.next(iter, session), session, (XMLRecord) row);
        nestedRows.addElement(nestedRow);
      }
      row.add(this.getForeignKeyGroupingElement(), nestedRows);
    } else {
      DatabaseField singleField = (DatabaseField) getSourceForeignKeyFields().get(0);
      DatabaseField pkField = (DatabaseField) getSourceForeignKeysToTargetKeys().get(singleField);
      for (Object iter = cp.iteratorFor(attributeValue); cp.hasNext(iter); ) {
        Object singleValue =
            getReferenceDescriptor()
                .getObjectBuilder()
                .extractValueFromObjectForField(cp.next(iter, session), pkField, session);
        row.add(singleField, singleValue);
      }
    }
  }
 /**
  * INTERNAL: This row is built for shallow insert which happens in case of bidirectional inserts.
  * The foreign keys must be set to null to avoid constraints.
  */
 public void writeFromObjectIntoRowForShallowInsertWithChangeRecord(
     ChangeRecord changeRecord, AbstractRecord row, AbstractSession session) {
   if (isForeignKeyRelationship() && !isReadOnly()) {
     if (getForeignKeyGroupingElement() != null) {
       row.put(getForeignKeyGroupingElement(), null);
     } else if (this.getSourceForeignKeyFields().size() > 0) {
       row.put(getSourceForeignKeyFields().get(0), null);
     }
   } else {
     super.writeFromObjectIntoRowForShallowInsertWithChangeRecord(changeRecord, row, session);
   }
 }
 /** INTERNAL: Get a value from the object and set that in the respective field of the row. */
 protected void writeFromNullObjectIntoRow(AbstractRecord record) {
   if (isReadOnly()) {
     return;
   }
   if (isForeignKeyRelationship()) {
     Enumeration foreignKeys = getForeignKeyFields().elements();
     while (foreignKeys.hasMoreElements()) {
       record.put((DatabaseField) foreignKeys.nextElement(), null);
     }
   }
   if (getTypeField() != null) {
     record.put(getTypeField(), null);
   }
 }
  /** INTERNAL: Write fields needed for insert into the template for with null values. */
  public void writeInsertFieldsIntoRow(AbstractRecord record, AbstractSession session) {
    if (isReadOnly()) {
      return;
    }

    record.put(getField(), null);
  }
  /**
   * INTERNAL: This row is built for shallow insert which happens in case of bidirectional inserts.
   * The foreign keys must be set to null to avoid constraints.
   */
  public void writeFromObjectIntoRowForShallowInsertWithChangeRecord(
      ChangeRecord changeRecord, AbstractRecord record, AbstractSession session) {
    if (isReadOnly()) {
      return;
    }

    record.put(getField(), null);
  }
  /** 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()));
      }
    }
  }
  /** INTERNAL: Get a value from the object and set that in the respective field of the row. */
  public void writeFromObjectIntoRow(
      Object object, AbstractRecord record, AbstractSession session) {
    if (isReadOnly()) {
      return;
    }

    Object referenceObject = getRealAttributeValueFromObject(object, session);

    if (referenceObject == null) {
      // Fix for 2730536, must put something in modify row, even if it is null.
      record.put(getField(), null);
      return;
    }

    Ref ref =
        ((ObjectRelationalDataTypeDescriptor) getReferenceDescriptor())
            .getRef(referenceObject, session);

    record.put(getField(), ref);
  }
  /**
   * 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: Get a value from the object and set that in the respective field of the row. */
  public void writeFromObjectIntoRowWithChangeRecord(
      ChangeRecord changeRecord, AbstractRecord record, AbstractSession session) {
    if (isReadOnly()) {
      return;
    }

    ObjectChangeSet changeSet =
        (ObjectChangeSet) ((ObjectReferenceChangeRecord) changeRecord).getNewValue();
    Object referenceObject = changeSet.getUnitOfWorkClone();

    if (referenceObject == null) {
      return;
    }

    Ref ref =
        ((ObjectRelationalDataTypeDescriptor) getReferenceDescriptor())
            .getRef(referenceObject, session);

    record.put(getField(), ref);
  }