private void handleError(JdbcConnection connection, Exception e)
     throws DatabaseException, CustomChangeException {
   connection.rollback();
   throw new CustomChangeException(e);
 }
  /** Method to perform validation and resolution of duplicate EncounterType names */
  @Override
  public void execute(Database database) throws CustomChangeException {
    JdbcConnection connection = (JdbcConnection) database.getConnection();
    Map<String, HashSet<Integer>> duplicates = new HashMap<String, HashSet<Integer>>();
    Statement stmt = null;
    PreparedStatement pStmt = null;
    ResultSet rs = null;

    try {
      // set auto commit mode to false for UPDATE action
      connection.setAutoCommit(false);

      stmt = connection.createStatement();
      rs =
          stmt.executeQuery(
              "SELECT * FROM encounter_type INNER JOIN (SELECT name FROM encounter_type GROUP BY name HAVING count(name) > 1) dup ON encounter_type.name = dup.name");

      Integer id = null;
      String name = null;

      while (rs.next()) {
        id = rs.getInt("encounter_type_id");
        name = rs.getString("name");

        if (duplicates.get(name) == null) {
          HashSet<Integer> results = new HashSet<Integer>();
          results.add(id);
          duplicates.put(name, results);
        } else {
          HashSet<Integer> results = duplicates.get(name);
          results.add(id);
        }
      }

      Iterator it2 = duplicates.entrySet().iterator();
      while (it2.hasNext()) {
        Map.Entry pairs = (Map.Entry) it2.next();

        HashSet values = (HashSet) pairs.getValue();
        List<Integer> editableNames = new ArrayList<Integer>(values);

        int duplicateNameId = 1;
        for (int i = 1; i < editableNames.size(); i++) {
          String newName = pairs.getKey() + "_" + duplicateNameId;

          List<List<Object>> duplicateResult = null;
          boolean duplicateName = false;
          Connection con = DatabaseUpdater.getConnection();

          do {
            String sqlValidatorString =
                "select * from encounter_type where name = '" + newName + "'";
            duplicateResult = DatabaseUtil.executeSQL(con, sqlValidatorString, true);

            if (!duplicateResult.isEmpty()) {
              duplicateNameId += 1;
              newName = pairs.getKey() + "_" + duplicateNameId;
              duplicateName = true;
            } else {
              duplicateName = false;
            }
          } while (duplicateName);

          pStmt =
              connection.prepareStatement(
                  "update encounter_type set name = ? where encounter_type_id = ?");
          pStmt.setString(1, newName);
          pStmt.setInt(2, editableNames.get(i));

          duplicateNameId += 1;

          pStmt.executeUpdate();
        }
      }
    } catch (BatchUpdateException e) {
      log.warn("Error generated while processsing batch insert", e);

      try {
        log.debug("Rolling back batch", e);
        connection.rollback();
      } catch (Exception rbe) {
        log.warn("Error generated while rolling back batch insert", e);
      }

      // marks the changeset as a failed one
      throw new CustomChangeException(
          "Failed to update one or more suplicate EncounterType names", e);
    } catch (DatabaseException e) {
      throw new CustomChangeException(
          "Error while updating duplicate EncounterType object names", e);
    } catch (SQLException e) {
      throw new CustomChangeException(
          "Error while updating duplicate EncounterType object names", e);
    } catch (DAOException e) {
      throw new CustomChangeException("Error accessing database connection", e);
    } catch (Exception e) {
      throw new CustomChangeException("Error accessing database connection", e);
    } finally {
      // reset to auto commit mode
      try {
        connection.setAutoCommit(true);
      } catch (DatabaseException e) {
        log.warn("Failed to reset auto commit back to true", e);
      }
      if (rs != null) {
        try {
          rs.close();
        } catch (SQLException e) {
          log.warn("Failed to close the resultset object");
        }
      }

      if (stmt != null) {
        try {
          stmt.close();
        } catch (SQLException e) {
          log.warn(
              "Failed to close the select statement used to identify duplicate EncounterType object names");
        }
      }

      if (pStmt != null) {
        try {
          pStmt.close();
        } catch (SQLException e) {
          log.warn(
              "Failed to close the prepared statement used to update duplicate EncounterType object names");
        }
      }
    }
  }