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;
   }
 }
  public void getChange(
      Record row,
      DatabaseMapping mapping,
      Session session,
      Object object1,
      Object object2,
      boolean useUOW,
      WriteType writeType) {
    if (mapping.isAggregateObjectMapping()) {
      Object aggregate1 = mapping.getAttributeValueFromObject(object1);
      Object aggregate2 = mapping.getAttributeValueFromObject(object2);
      if (aggregate1 == null && aggregate2 == null) {
        if (!useUOW) {
          mapping.writeFromObjectIntoRow(
              object2, (DatabaseRecord) row, (AbstractSession) session, writeType);
        }
      } else if (aggregate1 != null
          && aggregate2 != null
          && aggregate1.getClass().equals(aggregate2.getClass())) {
        ClassDescriptor desc = ((AggregateObjectMapping) mapping).getReferenceDescriptor();
        getChange(row, session, aggregate1, aggregate2, desc, useUOW, writeType);
      } else {
        mapping.writeFromObjectIntoRow(
            object2, (DatabaseRecord) row, (AbstractSession) session, writeType);
      }
    } else {
      Record row1 = new DatabaseRecord();
      Record row2 = new DatabaseRecord();
      mapping.writeFromObjectIntoRow(
          object1, (DatabaseRecord) row1, (AbstractSession) session, writeType);
      mapping.writeFromObjectIntoRow(
          object2, (DatabaseRecord) row2, (AbstractSession) session, writeType);

      for (int i = 0; i < row1.size(); i++) {
        DatabaseField field = (DatabaseField) ((DatabaseRecord) row1).getFields().elementAt(i);
        Object valueBefore = ((DatabaseRecord) row1).getValues().elementAt(i);
        Object valueAfter = row2.get(field);
        boolean changed;
        if (valueAfter == null) {
          changed = valueBefore != null;
        } else {
          changed = !valueAfter.equals(valueBefore);
        }
        if (changed) {
          row.put(field, valueAfter);
        }
      }
    }
  }
 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;
   }
 }