{"record":{"id":"a74ea492c24a8a0a","repo":"apache/seatunnel","slug":"field-is-null-setting-to-null-in-prepared-stat","errorCode":null,"errorMessage":"Field {} is null, setting to NULL in prepared statement","messagePattern":"Field (.+?) is null, setting to NULL in prepared statement","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"seatunnel-connectors-v2/connector-databend/src/main/java/org/apache/seatunnel/connectors/seatunnel/databend/sink/DatabendSinkWriter.java","lineNumber":672,"sourceCode":"                fieldTypes[i] = BasicType.DOUBLE_TYPE;\n            } else if (field instanceof Float) {\n                fieldTypes[i] = BasicType.FLOAT_TYPE;\n            } else if (field instanceof Boolean) {\n                fieldTypes[i] = BasicType.BOOLEAN_TYPE;\n            } else {\n                fieldTypes[i] = BasicType.STRING_TYPE;\n            }\n        }\n\n        return new SeaTunnelRowType(fieldNames, fieldTypes);\n    }\n\n    private void processRow(SeaTunnelRow row) throws SQLException {\n        log.info(\"Processing row with {} fields\", row.getFields().length);\n        for (int i = 0; i < row.getFields().length; i++) {\n            Object field = row.getFields()[i];\n            if (field == null) {\n                log.warn(\"Field {} is null, setting to NULL in prepared statement\", i + 1);\n                preparedStatement.setNull(i + 1, java.sql.Types.VARCHAR);\n            } else {\n                log.info(\n                        \"Setting parameter {}: {} ({})\",\n                        i + 1,\n                        field,\n                        field.getClass().getSimpleName());\n                preparedStatement.setObject(i + 1, field);\n            }\n        }\n        preparedStatement.addBatch();\n        log.info(\"Added row to batch, current batch count: {}\", batchCount + 1);\n    }\n\n    private void verifyRawTableData(String rawTableName, String database) throws SQLException {\n        try (Statement stmt = connection.createStatement();\n                ResultSet rs =\n                        stmt.executeQuery(","sourceCodeStart":654,"sourceCodeEnd":690,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-databend/src/main/java/org/apache/seatunnel/connectors/seatunnel/databend/sink/DatabendSinkWriter.java#L654-L690","documentation":"In DatabendSinkWriter.processRow(), each field of the row is bound to the PreparedStatement. When a field is null, the writer logs this warning and binds SQL NULL via setNull(i+1, Types.VARCHAR). This is informational: the write continues with a NULL in that column. Note it uses VARCHAR regardless of the column's real type, and will fail if the target column is NOT NULL.","triggerScenarios":"Any row containing a null field is processed in the traditional insert path (write -> processTraditionalRow -> processRow).","commonSituations":"Sparse/optional columns in source data; outer joins producing nulls; missing values in CSV/JSON sources; mapping mistakes leaving fields unpopulated. Fails with NOT NULL violation when the Databend column disallows NULL.","solutions":["If the column is NOT NULL in Databend, populate the field upstream or set a default value before the sink","Filter or coalesce null fields with a transform (e.g. CASE/COALESCE in SQL transform)","Verify field ordering matches the target table column order — nulls in the wrong position indicate mapping misalignment","If large volumes of this warning appear, disable per-field INFO/WARN logging in processRow — it is very hot-path heavy and slows throughput"],"exampleFix":"// before\nif (field == null) {\n    log.warn(\"Field {} is null, setting to NULL in prepared statement\", i + 1);\n    preparedStatement.setNull(i + 1, java.sql.Types.VARCHAR);\n}\n// after\nif (field == null) {\n    preparedStatement.setNull(i + 1, columnSqlTypes[i]); // correct JDBC type per column\n}","handlingStrategy":"validation","validationCode":"// pre-validate nulls against target NOT NULL columns\nfor (int i = 0; i < row.getFields().length; i++) {\n    if (row.getFields()[i] == null && notNullColumns.contains(i)) {\n        throw new IllegalArgumentException(\"Field \" + i + \" is NULL but column is NOT NULL\");\n    }\n}","typeGuard":"boolean hasNulls(SeaTunnelRow row) {\n    for (Object f : row.getFields()) { if (f == null) return true; }\n    return false;\n}","tryCatchPattern":"try {\n    writer.write(row);\n} catch (SQLException e) {\n    if (e.getMessage() != null && e.getMessage().toLowerCase().contains(\"null\")) {\n        log.error(\"NOT NULL constraint violated; null field bound to non-nullable column\", e);\n    }\n    throw e;\n}","preventionTips":["Coalesce/default null columns upstream before the sink","Match field order to target column order to avoid nulls landing in wrong columns","Reduce per-field logging in processRow for throughput on large datasets"],"tags":["null-values","jdbc","prepared-statement","data-quality"],"backgroundTag":"null-argument","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}