Java, Spring. Ошибка namedParameterJdbcTemplate
Хотел изменить подключение на datasource, но столкнулся с такой ошибкой:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'namedParameterJdbcTemplate' defined in class path resource [org/springframework/boot/autoconfigure/jdbc/NamedParameterJdbcTemplateConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate]: Factory method 'namedParameterJdbcTemplate' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/util/ConcurrentLruCache
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:657) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:637) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1336) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1176) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:556) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:516) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:324) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:322) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:897) ~[spring-beans-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.12.RELEASE.jar:5.2.12.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:405) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.6.RELEASE.jar:2.3.6.RELEASE]
at cinemaWorld.application.main(application.java:10) ~[classes/:na]
Код: SpringConfig
@Configuration
@ComponentScan("cinemaWorld")
@EnableWebMvc
public class SpringConfig implements WebMvcConfigurer {
private final ApplicationContext applicationContext;
@Autowired
public SpringConfig(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean
public SpringResourceTemplateResolver templateResolver() {
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
templateResolver.setApplicationContext(applicationContext);
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.setEnableSpringELCompiler(true);
return templateEngine;
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
registry.viewResolver(resolver);
}
@Bean
public DataSource dataSource() {
org.springframework.jdbc.datasource.DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/cinema");
dataSource.setUsername("root");
dataSource.setPassword("password");
System.out.println("Успешное подключение через datasourse");
return dataSource;
}}
Контроллер:
@Controller
@RequestMapping("/people")
public class PeopleController {
private PersonDAO personDAO;
@Autowired
public PeopleController(PersonDAO personDAO) {
this.personDAO = personDAO;
}
@GetMapping()
public String index(Model model) {
model.addAttribute("people", personDAO.index());
return "people/index";
}
@GetMapping("/{id}")
public String show(@PathVariable("id") int id, Model model ) {
model.addAttribute("person", personDAO.show(id));
return "people/show";
}
@GetMapping("/new")
public String newPerson(@ModelAttribute("person") Person person) {
return "people/new";
}
@PostMapping()
public String create(@ModelAttribute("person") Person person) {
personDAO.save(person);
return "redirect:/people";
} }
DAO:
@Controller
@RequestMapping("/people")
public class PeopleController {
private PersonDAO personDAO;
@Autowired
public PeopleController(PersonDAO personDAO) {
this.personDAO = personDAO;
}
@GetMapping()
public String index(Model model) {
// Получим всех людей из ДАО
// Передадим их всех на отображения
model.addAttribute("people", personDAO.index());
return "people/index";
}
@GetMapping("/{id}")
public String show(@PathVariable("id") int id, Model model ) {
// Получим одного человека по ИД из ДАО и передадим ег она оторажение в представление
model.addAttribute("person", personDAO.show(id));
return "people/show";
}
@GetMapping("/new")
public String newPerson(@ModelAttribute("person") Person person) {
return "people/new";
}
@PostMapping()
public String create(@ModelAttribute("person") Person person) {
personDAO.save(person);
return "redirect:/people";
}
application:
@SpringBootApplication
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class, args);
}
}
Изначально я дошел до использования JDBCtemplates в дао, но из-за этой же ошибки стал пошагово откатываться назад. В конечном итоге пришел к тому что при появлении datasource что-то идет не так. Как с этим бороться? Что исправить? Помогите пожалуйста.
Ответы (2 шт):
Проблема заключалась совместимостях. Spring-jdbc и spring-webmvc имели разные версии.
У меня была такая же ошибка, проблема заключалась в том, что на сервере был задеплоен компонент с более старшими версиями библиотеки Spring. Помогло то, что я у класса NamedParameterJdbcTemplate распечатал откуда classLoader загружает: namedParameterJdbcTemplate.getClass.getClassLoader().toString(). В распечатке было детально указано откуда берется класс, я сделал undeploy этого компонента и ошибка прошла.