{"record":{"id":"99583219174bd4db","repo":"pentaho/pentaho-kettle","slug":"row-metadata-and-data-unable-to-calculate-hashcode-because","errorCode":null,"errorMessage":"Row metadata and data: unable to calculate hashcode because of a data conversion problem","messagePattern":"Row metadata and data: unable to calculate hashcode because of a data conversion problem","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/pentaho/di/core/RowMetaAndData.java","lineNumber":107,"sourceCode":"   */\n  public RowMetaInterface getRowMeta() {\n    return rowMeta;\n  }\n\n  /**\n   * @param rowMeta\n   *          the rowMeta to set\n   */\n  public void setRowMeta( RowMetaInterface rowMeta ) {\n    this.rowMeta = rowMeta;\n  }\n\n  @Override\n  public int hashCode() {\n    try {\n      return rowMeta.hashCode( data );\n    } catch ( KettleValueException e ) {\n      throw new RuntimeException(\n        \"Row metadata and data: unable to calculate hashcode because of a data conversion problem\", e );\n    }\n  }\n\n  @Override\n  public boolean equals( Object obj ) {\n    try {\n      return rowMeta.compare( data, ( (RowMetaAndData) obj ).getData() ) == 0;\n    } catch ( KettleValueException e ) {\n      throw new RuntimeException(\n        \"Row metadata and data: unable to compare rows because of a data conversion problem\", e );\n    }\n  }\n\n  public void addValue( ValueMetaInterface valueMeta, Object valueData ) {\n    if ( valueMeta.isInteger() && ( valueData instanceof ObjectId ) ) {\n      valueData = new LongObjectId( (ObjectId) valueData ).longValue();\n    }","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/pentaho/pentaho-kettle/blob/f3058517a153da500bf4551f46d79b91bf8ec552/core/src/main/java/org/pentaho/di/core/RowMetaAndData.java#L89-L125","documentation":"RowMetaAndData.hashCode() delegates to rowMeta.hashCode(data), which computes a hash from the row's values. A KettleValueException there means a value could not be converted/hashed consistently with its metadata; the method rethrows it as a RuntimeException (hashCode cannot throw checked exceptions).","triggerScenarios":"Adding a RowMetaAndData to a HashSet/HashMap (triggering hashCode) when a field's value cannot be hashed per its ValueMeta — e.g. incompatible value type, malformed date/binary data, or metadata/data mismatch.","commonSituations":"Using RowMetaAndData objects as map keys or in sets during row comparison/join logic, rows constructed with wrong types vs declared metadata, custom ValueMeta converters throwing during hashing.","solutions":["Fix the metadata/data mismatch so each value matches its declared ValueMeta type","Inspect the cause KettleValueException to find the offending field/index","Avoid using rows with custom/unconvertible values as hash keys; compare explicitly with rowMeta.compare instead","Rebuild the row using ValueDataUtil conversions before hashing"],"exampleFix":"// before\nSet<RowMetaAndData> seen = new HashSet<>();\nseen.add(rowMetaAndData); // hashCode() may throw\n// after\nif (canHash(rowMetaAndData)) {\n  seen.add(rowMetaAndData);\n} else {\n  compareExplicitly(rowMetaAndData, seenRows); // rowMeta.compare based\n}","handlingStrategy":"try-catch","validationCode":"// pre-validate values are hashable per metadata\nfor (int i = 0; i < rmad.getRowMeta().size(); i++) {\n  try {\n    rmad.getRowMeta().getValueMeta(i).getNativeDataType(rmad.getData()[i]);\n  } catch (KettleValueException e) {\n    throw new IllegalStateException(\"Unhashable value at index \" + i, e);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  seen.add(rmad);\n} catch (RuntimeException e) {\n  // fall back to explicit rowMeta.compare based dedup instead of hashing\n}","preventionTips":["Avoid rows with metadata/value mismatches in hashed collections","Prefer rowMeta.compare for row equality instead of hashCode","Rebuild rows with proper ValueMeta conversions before adding to sets/maps"],"tags":["hashcode","row-metadata","conversion","collections"],"backgroundTag":"type-mismatch","analyzedSha":"f3058517a153da500bf4551f46d79b91bf8ec552","analyzedAt":"2026-09-13T14:04:16.340Z","contentChangedAt":"2026-09-13T14:04:16.340Z","schemaVersion":2},"datasetVersion":"2026-09-20T23:17:15.980Z"}