apache/seatunnel · error · JdbcConnectorException
UNSUPPORTED_DATA_TYPE
UNSUPPORTED_DATA_TYPE
Error message
Unexpected value:
What it means
setValueToStatementByDataType only implements JDBC parameter binding for scalar SeaTunnel types; MAP, ROW types (and any default/unknown case) hit the switch default and throw UNSUPPORTED_DATA_TYPE with 'Unexpected value: <type>'. The JDBC sink cannot flatten nested structures into a single SQL column via this converter path.
Source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/converter/AbstractJdbcRowConverter.java:353
Object[] array = (Object[]) value;
if (array == null) {
statement.setNull(statementIndex, java.sql.Types.ARRAY);
break;
}
if (SqlType.TINYINT.equals(elementType.getSqlType())) {
Short[] shortArray = new Short[array.length];
for (int i = 0; i < array.length; i++) {
shortArray[i] = Short.valueOf(array[i].toString());
}
statement.setObject(statementIndex, shortArray);
} else {
statement.setObject(statementIndex, array);
}
break;
case MAP:
case ROW:
default:
throw new JdbcConnectorException(
CommonErrorCodeDeprecated.UNSUPPORTED_DATA_TYPE,
"Unexpected value: " + seaTunnelDataType);
}
}
protected void writeTime(PreparedStatement statement, int index, LocalTime time)
throws SQLException {
statement.setTime(index, java.sql.Time.valueOf(time));
}
}
View on GitHub (pinned to cf67b549a7)
Solutions
- Flatten MAP/ROW fields into scalar columns before the JDBC sink (use a Transform to extract fields)
- If supported for your dialect, enable dialect-specific nested-type handling or upgrade SeaTunnel for broader type support
- Change the sink table/schema so nested data is serialized to a JSON string column first
- Check AbstractJdbcRowConverter's supported cases and pick a sink/converter that supports your type
Example fix
// before
field { name = "addr" type = ROW { city STRING zip STRING } } # goes to JDBC sink
// after
fields: addr_city STRING, addr_zip STRING (flatten with a Transform before sink) Defensive patterns
Strategy: validation
Validate before calling
for (SeaTunnelDataType t : rowType.getFieldTypes()) {
if (t instanceof MapType || t instanceof RowType || t instanceof ArrayType) {
throw new IllegalArgumentException("JDBC sink cannot bind nested type: " + t);
}
} Type guard
boolean isFlatScalar(SeaTunnelDataType<?> t) {
return !(t instanceof MapType) && !(t instanceof RowType) && !(t instanceof ArrayType);
} Try / catch
try {
converter.toExternal(row, statement);
} catch (JdbcConnectorException e) {
if (e.getErrorCode() == CommonErrorCodeDeprecated.UNSUPPORTED_DATA_TYPE) {
LOG.error("Flatten nested field before JDBC sink; offending type: {}", e.getMessage());
}
throw e;
} Prevention
- Flatten MAP/ROW/ARRAY fields with a Transform before relational sinks
- Serialize nested data to JSON strings if a single column is required
- Review the sink schema for nested types during job design review
- Check dialect-specific nested-type support before enabling it
When it happens
Trigger: toExternal() is called on a row whose schema contains a MAP or ROW field (or an otherwise unmapped data type), and the converter attempts to set that field on the PreparedStatement.
Common situations: Upstream source (e.g. JSON, MongoDB, Kafka) emits nested objects/arrays that flow unmodified into a JDBC sink; schema not flattened before writing to relational storage; missing dialect support for array/struct types for your database.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/c2cc97f5549ff0a0.
Report an issue: GitHub.