{"record":{"id":"c7c8e1ee2b3287f2","repo":"mybatis/mybatis-3","slug":"jdbc-requires-that-the-jdbctype-must-be-specified","errorCode":null,"errorMessage":"JDBC requires that the JdbcType must be specified for all nullable parameters.","messagePattern":"JDBC requires that the JdbcType must be specified for all nullable parameters\\.","errorType":"exception","errorClass":"TypeException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/type/BaseTypeHandler.java","lineNumber":62,"sourceCode":"\n  /**\n   * Sets the configuration.\n   *\n   * @param c\n   *          the new configuration\n   *\n   * @deprecated Since 3.5.0 - See https://github.com/mybatis/mybatis-3/issues/1203. This property will remove future.\n   */\n  @Deprecated\n  public void setConfiguration(Configuration c) {\n    this.configuration = c;\n  }\n\n  @Override\n  public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {\n    if (parameter == null) {\n      if (jdbcType == null) {\n        throw new TypeException(\"JDBC requires that the JdbcType must be specified for all nullable parameters.\");\n      }\n      try {\n        ps.setNull(i, jdbcType.TYPE_CODE);\n      } catch (SQLException e) {\n        throw new TypeException(\"Error setting null for parameter #\" + i + \" with JdbcType \" + jdbcType + \" . \"\n            + \"Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. \"\n            + \"Cause: \" + e, e);\n      }\n    } else {\n      try {\n        setNonNullParameter(ps, i, parameter, jdbcType);\n      } catch (Exception e) {\n        throw new TypeException(\"Error setting non null for parameter #\" + i + \" with JdbcType \" + jdbcType + \" . \"\n            + \"Try setting a different JdbcType for this parameter or a different configuration property. \" + \"Cause: \"\n            + e, e);\n      }\n    }\n  }","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/type/BaseTypeHandler.java#L44-L80","documentation":"JDBC drivers need a SQL type code to execute PreparedStatement.setNull. When a parameter value is null and MyBatis resolved no JdbcType for it (neither from #{param,jdbcType=...} nor from the environment's jdbcTypeForNull setting), BaseTypeHandler.setParameter throws this TypeException before touching the driver.","triggerScenarios":"Executing a statement where a nullable parameter is bound as #{value} with no jdbcType attribute while the effective jdbcTypeForNull resolution yields null; or invoking a TypeHandler.setParameter(ps, i, null, null) directly through the API.","commonSituations":"Optional search filters that are null on some requests; custom DefaultParameterHandler or programmatic SqlSource that drops the jdbcType; migrations between MyBatis versions where configuration defaults differ.","solutions":["Declare the type explicitly in the mapper: #{value,jdbcType=VARCHAR} (or the matching SQL type)","Set a global default in mybatis-config.xml: <setting name=\"jdbcTypeForNull\" value=\"NULL\"/> (or OTHER where the driver accepts it)","If calling TypeHandler.setParameter directly, always pass a non-null JdbcType for nullable values"],"exampleFix":"// before\nSELECT * FROM t WHERE name = #{name}\n\n// after\nSELECT * FROM t WHERE name = #{name,jdbcType=VARCHAR}","handlingStrategy":"validation","validationCode":"// before executing: ensure every nullable param has a jdbcType\nif (value == null && jdbcType == null) {\n  throw new IllegalStateException(\"Parameter '\" + name + \"' is null and has no jdbcType\");\n}","typeGuard":null,"tryCatchPattern":"try { sqlSession.selectOne(...) } catch (TypeException e) { if (e.getMessage().contains(\"JdbcType must be specified\")) { /* add jdbcType to mapper, rethrow otherwise */ } throw e; }","preventionTips":["Set jdbcTypeForNull globally instead of relying on per-parameter attributes","Adopt a mapper lint/review rule: every #{param} for a nullable column carries jdbcType","Cover the null-argument path of each query in tests"],"tags":["mybatis","jdbc","nullable","configuration","mapper"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}