Ошибка отражения Java Java.lang.NoSuchMethodException, но метод существует

Я не могу работать с отражением 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);

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

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

Но цикл for внутри метода selectOneAuto выводит метод с именем selectOne. Что здесь не так?


person tonis    schedule 18.02.2020    source источник


Ответы (1)


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

method.invoke (репозиторий, идентификатор);

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

Второй момент, который следует отметить, это то, что репозиторий уже является экземпляром класса, поэтому нет необходимости вызывать 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;
}
person Tarun Gupta    schedule 18.02.2020