@Transactional
  @Override
  public Map<String, Object> updateDatatableEntryOneToMany(
      final String datatable,
      final Long appTableId,
      final Long datatableId,
      final JsonCommand command) {

    final GenericResultsetData grs =
        retrieveDataTableGenericResultSet(datatable, appTableId, null, datatableId);

    if (grs.getData().size() == 0) throw new DatatableNotFoundException(datatable, appTableId);

    final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
    final Map<String, String> dataParams =
        this.fromJsonHelper.extractDataMap(typeOfMap, command.json());

    final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, "id");

    if (changes.size() == 0) return changes;

    final String sql = getUpdateSql(datatable, "id", datatableId, changes);

    if (StringUtils.isNotBlank(sql)) {
      this.jdbcTemplate.update(sql);
    } else {
      logger.info("No Changes");
    }

    return changes;
  }
  private Map<String, Object> getAffectedAndChangedColumns(
      final GenericResultsetData grs, final Map<String, String> queryParams, final String fkName) {

    final Map<String, String> affectedColumns =
        getAffectedColumns(grs.getColumnHeaders(), queryParams, fkName);
    final Map<String, Object> affectedAndChangedColumns = new HashMap<String, Object>();

    for (final String key : affectedColumns.keySet()) {
      final String columnValue = affectedColumns.get(key);
      final String colType = grs.getColTypeOfColumnNamed(key);
      if (columnChanged(key, columnValue, colType, grs)) {
        affectedAndChangedColumns.put(key, columnValue);
      }
    }

    return affectedAndChangedColumns;
  }
  private boolean columnChanged(
      final String key,
      final String keyValue,
      final String colType,
      final GenericResultsetData grs) {

    List<String> columnValues = grs.getData().get(0).getRow();

    String columnValue = null;
    for (int i = 0; i < grs.getColumnHeaders().size(); i++) {

      if (key.equals(grs.getColumnHeaders().get(i).getColumnName())) {
        columnValue = columnValues.get(i);

        if (notTheSame(columnValue, keyValue, colType)) {
          return true;
        }
        return false;
      }
    }

    throw new PlatformDataIntegrityException(
        "error.msg.invalid.columnName", "Parameter Column Name: " + key + " not found");
  }
  @Transactional
  @Override
  public Map<String, Object> updateDatatableEntryOneToOne(
      final String datatable, final Long appTableId, final JsonCommand command) {

    final GenericResultsetData grs =
        retrieveDataTableGenericResultSet(datatable, appTableId, null, null);

    if (grs.hasNoEntries()) {
      throw new DatatableNotFoundException(datatable, appTableId);
    }

    if (grs.hasMoreThanOneEntry()) {
      throw new PlatformDataIntegrityException(
          "error.msg.attempting.multiple.update",
          "Application table: " + datatable + " Foreign key id: " + appTableId);
    }

    final String fkName = getFKField(queryForApplicationTableName(datatable));

    final Type typeOfMap = new TypeToken<Map<String, String>>() {}.getType();
    Map<String, String> dataParams = this.fromJsonHelper.extractDataMap(typeOfMap, command.json());

    final Map<String, Object> changes = getAffectedAndChangedColumns(grs, dataParams, fkName);

    if (!changes.isEmpty()) {
      final String updateOneToOneDatatableSql =
          getUpdateSql(datatable, fkName, appTableId, changes);

      if (StringUtils.isNotBlank(updateOneToOneDatatableSql)) {
        this.jdbcTemplate.update(updateOneToOneDatatableSql);
      }
    }

    return changes;
  }