解決org.apache.ibatis.executor.ExecutorException: No constructor found in xxxBean問題
阿新 • • 發佈:2019-02-19
在使用mybatis時遇到該問題,解決方法很簡單,在實體類bean中加一個無參的構造方法即可,具體原因如下:
相關原始碼如下:
private Object createByConstructorSignature(ResultSetWrapper rsw, Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs,
String columnPrefix) throws SQLException {
for (Constructor<?> constructor : resultType.getDeclaredConstructors()) {
if (typeNames(constructor.getParameterTypes()).equals(rsw.getClassNames())) {
boolean foundValues = false;
for (int i = 0; i < constructor.getParameterTypes().length; i++) {
Class<?> parameterType = constructor.getParameterTypes()[i];
String columnName = rsw.getColumnNames().get (i);
TypeHandler<?> typeHandler = rsw.getTypeHandler(parameterType, columnName);
Object value = typeHandler.getResult(rsw.getResultSet(), prependPrefix(columnName, columnPrefix));
constructorArgTypes.add(parameterType);
constructorArgs.add(value);
foundValues = value != null || foundValues;
}
return foundValues ? objectFactory.create(resultType, constructorArgTypes, constructorArgs) : null;
}
}
throw new ExecutorException("No constructor found in " + resultType.getName() + " matching " + rsw.getClassNames());
}
從上述程式碼可以看出當建立物件來接受sql結果時會遍歷實體類的構造方法找到與之匹配的,如果實體類中有構造方法了但是引數不匹配的話就會報上述錯誤,此時新增無參構造方法(預設的構造方法),會走其他方法,具體程式碼如下:
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix)
throws SQLException {
final Class<?> resultType = resultMap.getType();
final MetaClass metaType = MetaClass.forClass(resultType, reflectorFactory);
final List<ResultMapping> constructorMappings = resultMap.getConstructorResultMappings();
if (typeHandlerRegistry.hasTypeHandler(resultType)) {
return createPrimitiveResultObject(rsw, resultMap, columnPrefix);
} else if (!constructorMappings.isEmpty()) {
return createParameterizedResultObject(rsw, resultType, constructorMappings, constructorArgTypes, constructorArgs, columnPrefix);
} else if (resultType.isInterface() || metaType.hasDefaultConstructor()) {//有無參構造方法時走這裡
return objectFactory.create(resultType);
} else if (shouldApplyAutomaticMappings(resultMap, false)) {//有構造方法但無預設構造方法
return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs, columnPrefix);
}
throw new ExecutorException("Do not know how to create an instance of " + resultType);
}