{"record":{"id":"2cfd54aff610caad","repo":"mybatis/mybatis-3","slug":"mapper-method-name-attempted-to-return-null-fr","errorCode":null,"errorMessage":"Mapper method '{name}' attempted to return null from a method with a primitive return type ({returnType}).","messagePattern":"Mapper method '(.+?)' attempted to return null from a method with a primitive return type \\((.+?)\\)\\.","errorType":"exception","errorClass":"BindingException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/apache/ibatis/binding/MapperMethod.java","lineNumber":100,"sourceCode":"          result = executeForMap(sqlSession, args);\n        } else if (method.returnsCursor()) {\n          result = executeForCursor(sqlSession, args);\n        } else {\n          Object param = method.convertArgsToSqlCommandParam(args);\n          result = sqlSession.selectOne(command.getName(), param);\n          if (method.returnsOptional() && (result == null || !method.getReturnType().equals(result.getClass()))) {\n            result = Optional.ofNullable(result);\n          }\n        }\n        break;\n      case FLUSH:\n        result = sqlSession.flushStatements();\n        break;\n      default:\n        throw new BindingException(\"Unknown execution method for: \" + command.getName());\n    }\n    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {\n      throw new BindingException(\"Mapper method '\" + command.getName()\n          + \"' attempted to return null from a method with a primitive return type (\" + method.getReturnType() + \").\");\n    }\n    return result;\n  }\n\n  private Object rowCountResult(int rowCount) {\n    final Object result;\n    if (method.returnsVoid()) {\n      result = null;\n    } else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {\n      result = rowCount;\n    } else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {\n      result = (long) rowCount;\n    } else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {\n      result = rowCount > 0;\n    } else {\n      throw new BindingException(\n          \"Mapper method '\" + command.getName() + \"' has an unsupported return type: \" + method.getReturnType());","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/mybatis/mybatis-3/blob/008069adb1b089579b5dcba87ee591908b263274/src/main/java/org/apache/ibatis/binding/MapperMethod.java#L82-L118","documentation":"A mapper method declared with a primitive return type (int, boolean, long, ...) executed a query that returned null. Java cannot unbox null into a primitive, so MyBatis fails fast with a BindingException instead of throwing a bare NullPointerException at the call site.","triggerScenarios":"Mapper method like 'int findAge(Long id)' where selectOne returns no row; INSERT/UPDATE/DELETE methods declared with primitive types not covered by rowCountResult (which does handle int/long/boolean); a SELECT method with primitive return whose query yields zero rows.","commonSituations":"Querying by an id that does not exist; filters that match nothing; changing a wrapper return type (Integer) to a primitive (int) during refactoring.","solutions":["Change the mapper method return type from primitive to its wrapper (int -> Integer, boolean -> Boolean) and handle null at the call site","If the query should always return a row, fix the WHERE clause or the data so a row is always matched","Add COALESCE/IFNULL in SQL so the database returns a non-null scalar instead of no row"],"exampleFix":"// before\nint findAge(@Param(\"id\") Long id);\n// after\nInteger findAge(@Param(\"id\") Long id); // caller handles null","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"static boolean safePrimitiveReturn(Class<?> rt) {\n  return !rt.isPrimitive(); // prefer wrappers in mapper signatures\n}","tryCatchPattern":"catch (BindingException e) { if (e.getMessage().contains(\"primitive return type\")) return defaultValue; throw e; }","preventionTips":["Use wrapper types (Integer/Boolean/Long) in mapper signatures instead of primitives","Write one integration test per mapper method covering the zero-rows case"],"tags":["mybatis","binding","null-return","primitive-type"],"backgroundTag":null,"analyzedSha":"008069adb1b089579b5dcba87ee591908b263274","analyzedAt":"2026-08-14T13:07:10.264Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}