{"record":{"id":"90b2828bb6b0fb6d","repo":"mybatis/mybatis-3","slug":"type-argument-cannot-be-null","errorCode":null,"errorMessage":"Type argument cannot be null","messagePattern":"Type argument cannot be null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/type/EnumOrdinalTypeHandler.java","lineNumber":33,"sourceCode":" */\npackage org.apache.ibatis.type;\n\nimport java.sql.CallableStatement;\nimport java.sql.PreparedStatement;\nimport java.sql.ResultSet;\nimport java.sql.SQLException;\n\n/**\n * @author Clinton Begin\n */\npublic class EnumOrdinalTypeHandler<E extends Enum<E>> extends BaseTypeHandler<E> {\n\n  private final Class<E> type;\n  private final E[] enums;\n\n  public EnumOrdinalTypeHandler(Class<E> type) {\n    if (type == null) {\n      throw new IllegalArgumentException(\"Type argument cannot be null\");\n    }\n    this.type = type;\n    this.enums = type.getEnumConstants();\n    if (this.enums == null) {\n      throw new IllegalArgumentException(type.getSimpleName() + \" does not represent an enum type.\");\n    }\n  }\n\n  @Override\n  public void setNonNullParameter(PreparedStatement ps, int i, E parameter, JdbcType jdbcType) throws SQLException {\n    ps.setInt(i, parameter.ordinal());\n  }\n\n  @Override\n  public E getNullableResult(ResultSet rs, String columnName) throws SQLException {\n    int ordinal = rs.getInt(columnName);\n    if (ordinal == 0 && rs.wasNull()) {\n      return null;","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/type/EnumOrdinalTypeHandler.java#L15-L51","documentation":"EnumOrdinalTypeHandler caches the enum constants at construction and requires the enum Class to do so. Passing a null Class to the constructor throws this IllegalArgumentException immediately — the handler refuses to operate without knowing the enum type.","triggerScenarios":"new EnumOrdinalTypeHandler<>(null); or registering the handler in XML/Configuration without a javaType so TypeHandlerRegistry instantiates it with a null type argument; default enum handling when the java type of a property could not be resolved.","commonSituations":"Declaring <typeHandler handler=\"...EnumOrdinalTypeHandler\"/> with no javaType attribute; a mapper property whose javaType is left unresolved (e.g. generic erased fields) so MyBatis falls back to a null-typed enum handler.","solutions":["Always declare javaType when registering: <typeHandler handler=\"...EnumOrdinalTypeHandler\" javaType=\"com.example.MyEnum\"/>","Ensure the mapper property/parameter has a resolvable java type (add javaType= to #{...} or the resultMap)","If constructing programmatically, never pass null — load the enum class first"],"exampleFix":"// before\n<typeHandler handler=\"org.apache.ibatis.type.EnumOrdinalTypeHandler\"/>\n\n// after\n<typeHandler handler=\"org.apache.ibatis.type.EnumOrdinalTypeHandler\" javaType=\"com.example.Status\"/>","handlingStrategy":"validation","validationCode":"if (enumClass == null) throw new IllegalArgumentException(\"enumClass required for EnumOrdinalTypeHandler\");\nreturn new EnumOrdinalTypeHandler<>(enumClass);","typeGuard":"static <E extends Enum<E>> EnumOrdinalTypeHandler<E> safeOrdinalHandler(Class<E> type) {\n  return type == null ? null : new EnumOrdinalTypeHandler<>(type);\n}","tryCatchPattern":"try { new EnumOrdinalTypeHandler<>(type); } catch (IllegalArgumentException e) { // null or non-enum type: fix registration }","preventionTips":["Always pair enum handler registrations with an explicit javaType","Static-check configuration at startup: enumerate <typeHandler> entries and assert javaType is set for enum handlers"],"tags":["mybatis","enum","type-handler","configuration"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}