Java ошибка отражения Java .lang.NoSuchMethodException, но метод существует - PullRequest
1 голос
/ 18 февраля 2020

Я не могу приступить к работе java Отражение в загрузке Spring с Controller и JdbcTemplate.

Контроллер по умолчанию выглядит следующим образом:

public class DefaultController {

private static final Logger logger = LoggerFactory.getLogger(DefaultController.class);

public JsonResponseDataModel selectOneAuto(Long id, Class<?> repository, HttpServletResponse response){

    final JsonResponseDataModel result = new JsonResponseDataModel();
    System.out.println("The name of class is " + repository.getName());

    Method[] methods = repository.getMethods();
    for (Method method : methods) {
        System.out.println("Method: " + method.getName());
    }

    try {
        //Method method = repository.getClass().getMethod("selectOne", Long.class);
        Method method = repository.getClass().getDeclaredMethod("selectOne", Long.class);
        method.invoke(repository, id);

        logger.info("selectOneAuto : id={} ", id);
    } catch (EmptyResultDataAccessException e) {
        result.setEmptyResultDataAccessException("id", id.toString());
    } catch (DataAccessException e) {            
        e.printStackTrace();            
    } catch (NoSuchMethodException e) {            
        e.printStackTrace();            
    } catch (IllegalAccessException e) {            
        e.printStackTrace();            
    } catch (InvocationTargetException e) {            
        e.printStackTrace();            
    }
    return result;
}

}

Внутри класса CompanyRepository определен метод selectOne с Длинный ввод:

@Transactional(readOnly=true)
     public CompanyModel selectOne(Long id) {
     CompanyModel result = null;
     final String sql = "SELECT * FROM company WHERE id=?";
     return jdbcTemplate.queryForObject(sql, new Object[]{id}, new CompanyRowMapper());
}

Когда я создаю новый класс «CompanyController extends DefaultController» и вызывает метод selectOneAuto:

selectOneAuto(id, new CompanyRepository().getClass(), response);

Затем он заканчивается ошибкой в ​​строке «Метод method = репозиторий». getClass (). getDeclaredMethod ("selectOne", Long.class); "

"Java.lang.NoSuchMethodException: java.lang.Class.selectOne(java.lang.Long)"

Но для l oop внутри метода" selectOneAuto "выводится метод с именем" selectOne ". Что здесь не так?

1 Ответ

1 голос
/ 18 февраля 2020

Ваш код пытается вызвать метод в экземпляре Class.

method.invoke (хранилище, id);

объект хранилища является экземпляром Class, так как вы передаете new CompanyRepository().getClass() в качестве параметра.

Второй момент, который следует отметить, это то, что репозиторий уже является экземпляром Class, поэтому нет необходимости вызывать getClass () для этого объекта.

Вы должны получить объект метода, используя следующий код:

Method method = repository.getDeclaredMethod("selectOne", Long.class);

И тогда это должно сработать:

CompanyRepository repsitoryObj = new CompanyRepository();
method.invoke(repsitoryObj, id);

Или лучше и чище - просто изменить тип параметра repository на CompanyRepository, ваш метод будет выглядеть следующим образом:

public JsonResponseDataModel selectOneAuto(Long id, CompanyRepository repository, HttpServletResponse response){

    final JsonResponseDataModel result = new JsonResponseDataModel();
    System.out.println("The name of class is " + repository.getClass().getName());

    Method[] methods = repository.getClass().getMethods();
    for (Method method : methods) {
    System.out.println("Method: " + method.getName());
    }

    try {
    //Method method = repository.getClass().getMethod("selectOne", Long.class);
    Method method = repository.getClass().getDeclaredMethod("selectOne", Long.class);
    method.invoke(repository, id);

    logger.info("selectOneAuto : id={} ", id);
    } catch (EmptyResultDataAccessException e) {
    result.setEmptyResultDataAccessException("id", id.toString());
    } catch (DataAccessException e) {            
    e.printStackTrace();            
    } catch (NoSuchMethodException e) {            
    e.printStackTrace();            
    } catch (IllegalAccessException e) {            
    e.printStackTrace();            
    } catch (InvocationTargetException e) {            
    e.printStackTrace();            
    }
    return result;
}
...