getting error:Error creating bean with name '*': Unsatisfied dependency expressed through field 'repo'; n - spring

Error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'issueTemplateServiceImpl': Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.conseco.repository.IssueTemplateRepo' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:400)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4840)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5303)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1407)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1397)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.conseco.repository.IssueTemplateRepo' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 24 more
My code:
IssueTemplateController:
package com.conseco.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.conseco.dao.IssueTemplateInfo;
import com.conseco.service.IssueTemplateService;
#Controller
public class IssueTemplateController {
#Autowired
IssueTemplateService service;
#RequestMapping("/new")
public ModelAndView create()
{
System.out.println("service: "+service);
ModelAndView mav=new ModelAndView("index");
System.out.println("1..................");
IssueTemplateInfo issue=new IssueTemplateInfo();
issue.setSDT("123456");
issue.setAnalysis("test");
issue.setApplicaiton("AWD");
issue.setBatch("no");
issue.setBusinessImpact("N/A");
issue.setDescription("will describe later");
issue.setEMER("N/A");
issue.setImpDate("25th");
issue.setPermanentFix("TBT");
issue.setQCDefect("234");
issue.setRootCause("unknown");
issue.setSeverity(3);
issue.setStatus("Inprogress");
issue.setWorkAround("a lot to work on");
service.save(issue);
System.out.println("4..............");
return mav;
}
}
MyFrontController:
package com.conseco.controller;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import com.conseo.config.WebMvcConfig;
public class MyFrontController extends AbstractAnnotationConfigDispatcherServletInitializer{
#Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class[] {WebMvcConfig.class};
}
#Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
}
#Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
return new String[] {"/"};
}
}
IssueTemplateRepo:
package com.conseco.repository;
import org.springframework.data.repository.CrudRepository;
import com.conseco.dao.IssueTemplateInfo;
public interface IssueTemplateRepo extends CrudRepository<IssueTemplateInfo, String> {
}
IssueTemplateService:
package com.conseco.service;
import org.springframework.stereotype.Service;
import com.conseco.dao.IssueTemplateInfo;
public interface IssueTemplateService {
IssueTemplateInfo save(IssueTemplateInfo issue);
}
IssueTemplateServiceImpl:
package com.conseco.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.conseco.dao.IssueTemplateInfo;
import com.conseco.repository.IssueTemplateRepo;
#Service
public class IssueTemplateServiceImpl implements IssueTemplateService {
#Autowired
private IssueTemplateRepo repo;
public IssueTemplateRepo getRepo() {
return repo;
}
public void setRepo(IssueTemplateRepo repo) {
this.repo = repo;
}
#Override
public IssueTemplateInfo save(IssueTemplateInfo issue) {
// TODO Auto-generated method stub
return repo.save(issue);
}
}
WebMvcConfigurer:
package com.conseo.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
#Configuration
#EnableWebMvc
#ComponentScan({"com.conseco.service","com.conseco.controller","com.conseco.repository","com.conseco.dao"})
public class WebMvcConfig implements WebMvcConfigurer {
}

Add the annotation #Component on the interface:
#Component
public interface IssueTemplateRepo extends CrudRepository<IssueTemplateInfo, String> {
}
After you add the #Component annotation will become a spring bean and it can be managed managed by the Spring IoC container.

Related

No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc

Spring boot 2
build.gradle:
dependencies {
implementation 'com.google.code.gson:gson:2.7'
implementation 'com.h2database:h2'
implementation 'javax.servlet:jstl:1.2'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.apache.tomcat.embed:tomcat-embed-jasper'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
}
test {
useJUnitPlatform()
}
User model:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
#Entity
public class User {
#Id
#GeneratedValue
private long id;
#NotNull
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public String toString() {
return "\nUser{" +
"id = " + id +
", name = '" + name + '\'' +
'}';
}
}
in my controller:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
#RestController
public class UserController {
private UserRepository userRepository;
// If class has only one constructore then #Autowired wiil execute automatically
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
User user = new User();
user.setName("Peter");
userRepository.save(user);
}
#GetMapping("/users")
public List<User> getAllUsers() {
List<User> usersList = new ArrayList<>();
userRepository.findAll().forEach(usersList::add);
return usersList;
}
}
My repo:
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Integer> {
}
and here my test:
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#SpringBootTest
public class UserControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private UserRepository userVehicleService;
#Test
public void testExample() throws Exception {
List<User> userList = new ArrayList<>();
User user = new User();
user.setName("Peter");
userList.add(user);
given(this.userVehicleService.findAll()).willReturn(userList);
this.mockMvc.perform(MockMvcRequestBuilders.get("/users").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string("[{\"id\":\"1\",\"name\":\"Peter\"}]"));
}
}
Error creating bean with name 'com.myproject.UserControllerTest': Unsatisfied dependency expressed through field 'mockMvc'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.myproject.UserControllerTest': Unsatisfied dependency expressed through field 'mockMvc'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:643)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1422)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:393)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:119)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:43)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:244)
at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:98)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$5(ClassBasedTestDescriptor.java:337)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.executeAndMaskThrowable(ClassBasedTestDescriptor.java:342)
at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeTestInstancePostProcessors$6(ClassBasedTestDescriptor.java:337)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.test.web.servlet.MockMvc' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1695)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1253)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1207)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
... 92 more
com.myproject.UserControllerTest > testExample() FAILED
org.springframework.beans.factory.UnsatisfiedDependencyException
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException
1 test completed, 1 failed
But when start test I get error:
Add #AutoConfigureMockMvc to your test class.

Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'securityService'

SecurityConfig
package com.book.entity.security.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
private SecurityService securityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = { "/css/**", "/js/**", "/image/**", "/", "/myAccount" };
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().
/* antMatchers("/**"). */
antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();
http.csrf().disable().cors().disable().formLogin().failureUrl("/login?error").defaultSuccessUrl("/")
.loginPage("/login").permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/?logout")
.deleteCookies("remember-me").permitAll().and().rememberMe();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityService).passwordEncoder(passwordEncoder());
}
}
SecurityUtility
package com.book.entity.security.impl;
import java.security.SecureRandom;
import java.util.Random;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
#Component
public class SecurityUtility {
private static final String SALT = "salt"; // Salt should be protected carefully
#Bean
public static BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));
}
#Bean
public static String randomPassword() {
String SALTCHARS = "ABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder salt = new StringBuilder();
Random rnd = new Random();
while (salt.length() < 18) {
int index = (int) (rnd.nextFloat() * SALTCHARS.length());
salt.append(SALTCHARS.charAt(index));
}
String saltStr = salt.toString();
return saltStr;
}
}
UserRepository
package com.book.entity.security.impl;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.book.entity.User;
#Repository
public interface UserRepository extends JpaRepository<User, Long>{
User findByUsername(String userName);
}
SecurityService
package com.book.entity.security.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.book.entity.User;
#Service
public class SecurityService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userRepository.findByUsername(userName);
if (null == user) {
throw new UsernameNotFoundException("Username not found");
}
return user;
}
}
Error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'securityService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityService': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.book.entity.User com.book.entity.security.impl.UserRepository.findByUsername(java.lang.String)! Unable to locate Attribute with the the given name [username] on this ManagedType [com.book.entity.User]

public org.demo.ComplaintQueryObject org.demo.DemoComplaintsApplication$ComplaintAPI.find(java.lang.String) mapped

I am developing Spring Boot + Axon + CQRS example. In this example, while starting the main method, I get the below error.
Looks like String cant be used in place of the ID. I tried to convert String to ID but it doesn't worked well.
Could you please guide me what should be done ? Here is the my whole source code.
Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'demoComplaintsApplication.ComplaintAPI' method
public java.util.List<org.demo.ComplaintQueryObject> org.demo.DemoComplaintsApplication$ComplaintAPI.findAll()
to {[],methods=[GET]}: There is already 'demoComplaintsApplication.ComplaintAPI' bean method
public org.demo.ComplaintQueryObject org.demo.DemoComplaintsApplication$ComplaintAPI.find(java.lang.String) mapped.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1694) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:573) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:495) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:317) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:315) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:759) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:548) ~[spring-context-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:386) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:307) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
at org.demo.DemoComplaintsApplication.main(DemoComplaintsApplication.java:31) [classes/:na]
Caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'demoComplaintsApplication.ComplaintAPI' method
public java.util.List<org.demo.ComplaintQueryObject> org.demo.DemoComplaintsApplication$ComplaintAPI.findAll()
to {[],methods=[GET]}: There is already 'demoComplaintsApplication.ComplaintAPI' bean method
public org.demo.ComplaintQueryObject org.demo.DemoComplaintsApplication$ComplaintAPI.find(java.lang.String) mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:581) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:545) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:267) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lambda$detectHandlerMethods$1(AbstractHandlerMethodMapping.java:252) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at java.util.LinkedHashMap.forEach(Unknown Source) ~[na:1.8.0_162]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:250) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:219) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:189) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:136) ~[spring-webmvc-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1753) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1690) ~[spring-beans-5.0.10.RELEASE.jar:5.0.10.RELEASE]
... 16 common frames omitted
Code:
package org.demo;
import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import static org.axonframework.commandhandling.model.AggregateLifecycle.apply;
import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.commandhandling.gateway.CommandGateway;
import org.axonframework.eventhandling.EventHandler;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.spring.stereotype.Aggregate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#SpringBootApplication
public class DemoComplaintsApplication {
public static void main(String[] args) {
SpringApplication.run(DemoComplaintsApplication.class, args);
}
#RestController
public static class ComplaintAPI {
private final ComplaintQueryObjectRepository repostory;
private final CommandGateway commandGateway;
public ComplaintAPI(ComplaintQueryObjectRepository repostory, CommandGateway commandGateway) {
this.repostory = repostory;
this.commandGateway = commandGateway;
}
#PostMapping
public CompletableFuture<Object> fileCompplaint(#RequestBody Map<String, String> request) {
String id = UUID.randomUUID().toString();
return commandGateway
.send(new FileComplaintCommand(id, request.get("company"), request.get("description")));
}
#GetMapping
public List<ComplaintQueryObject> findAll() {
return repostory.findAll();
}
#GetMapping
public ComplaintQueryObject find(#PathVariable String id) {
return repostory.findById(id).get();
}
}
#Aggregate
public static class Complaint {
#AggregateIdentifier
private String complaintId;
public Complaint() {
super();
}
#CommandHandler
public Complaint(FileComplaintCommand command) {
Assert.hasLength(command.getCompany());
apply(new ComplaintFileEvent(command.getId(), command.getCompany(), command.getDescription()));
}
#EventSourcingHandler
public void on(ComplaintFileEvent event) {
this.complaintId = event.getId();
}
}
#Component
public static class ComplaintQueryObjectUpdater {
private final ComplaintQueryObjectRepository repository;
public ComplaintQueryObjectUpdater(ComplaintQueryObjectRepository repository) {
this.repository = repository;
}
#EventHandler
public void on(ComplaintFileEvent event) {
repository.save(new ComplaintQueryObject(event.getId(), event.getCompany(), event.getDescription()));
}
}
public static class FileComplaintCommand {
private String id;
private String company;
private String description;
public FileComplaintCommand(String id, String company, String description) {
super();
this.id = id;
this.company = company;
this.description = description;
}
public String getId() {
return id;
}
public String getCompany() {
return company;
}
public String getDescription() {
return description;
}
}
}
This error is related to ambiguity that means you have multiple method with the same mappings.Change the second method by specifying path variable #GetMapping("/{id}")
#GetMapping("/{id}")
public ComplaintQueryObject find(#PathVariable String id) {
return repostory.findById(id).get();
}

Unsatisfied dependency expressed through field - Springboot the Application, the component and the test class are all in the same package

My understanding is that the SpringBootApplication annotation includes
ComponentScan
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html
The bean is discovered and printed in Application.main(), why does the unit test not find it?
This unit test fails with:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.pds.pdssr.etlfile.EtlFileServicesTest': Unsatisfied dependency expressed through field 'etlFileServices'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.pds.pdssr.etlfile.EtlFileServices' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
With the appropriate level of debug, i.e "org.springframework.context.annotation"="debug" I can see that the bean was discovered during component scanning.
Nevertheless, the unit test results in:
[ERROR] getAll(com.pds.pdssr.etlfile.EtlFileServicesTest) Time elapsed: 0.007 s <<< ERROR!
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.pds.pdssr.etlfile.EtlFileServicesTest': Unsatisfied dependency expressed through field 'etlFileServices'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.pds.pdssr.etlfile.EtlFileServices' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.pds.pdssr.etlfile.EtlFileServices' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
The Application:
package com.pds.pdssr.bootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
//#EnableJpaRepositories("com.pds.pdsssr.jpa")
#SpringBootApplication
// #EntityScan("com.pds.pdssr.models")
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
for (String name : applicationContext.getBeanDefinitionNames()) {
logger.info("bean: " + name);
}
}
}
The Component:
package com.pds.pdssr.bootstrap;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import javax.transaction.Transactional;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.pds.pdssr.models.EtlFile;
#Repository
public class EtlFileServices {
#Autowired
private static EntityManagerFactory entityManagerFactory;
public SessionFactory getSessionFactory() {
SessionFactory sessionFactory = null;
if (entityManagerFactory == null) {
throw new IllegalStateException("entityManagerFactory is null");
}
sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
if (sessionFactory == null) {
throw new NullPointerException("factory is not a hibernate factory");
}
return sessionFactory;
}
#SuppressWarnings("unchecked")
public List<EtlFile> getAll() {
return getAll("etlFile",getSessionFactory().getCurrentSession());
}
#SuppressWarnings("rawtypes")
protected List getAll(String tableName, Session session) {
String queryText = "from " + tableName;
return getList(tableName, queryText, session);
}
#SuppressWarnings("rawtypes")
protected List getList(String tableName, String queryText, Session session) {
long start = System.nanoTime();
Query query = session.createQuery(queryText);
List result = query.list();
long end = System.nanoTime();
long millis = (end - start) / 1000000;
//logger.debug("table: " + tableName + " millis " + millis + " rows: " + result.size());
return result;
}
}
The test class:
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import com.pds.pdssr.bootstrap.EtlFileServices;
import com.pds.pdssr.models.EtlFile;
#RunWith(SpringRunner.class)
public class EtlFileServicesTest {
#Autowired
private EtlFileServices etlFileServices;
#Test
public void getAll() {
List<EtlFile> etlFiles = etlFileServices.getAll();
assertNotNull(etlFiles);
}
}
Original answer:
You need to have
#RunWith(SpringRunner.class)
#SpringBootTest(classes = YourMainClass.class)
in your test class(es).
Further answer based on comment
If you really want to have SessionFactory in your project, you need to tell spring framework to have SessionContext explicitly. It can be done by add
spring.jpa.properties.hibernate.current_session_context_class = org.springframework.orm.hibernate5.SpringSessionContext
to your configuration file. Here's a working example for your problem.
HTH

NoSuchBeanDefinitionException Spring 3.2.2 Hibernate 4 using annotation configuration building with Maven 3

What am I missing?
I am trying to create a basic SpringMVC application using Hibernate. I have another SpringMVC application that I model it after and it works.
I have apparently missed something and I am at a loss. Any help here would be much appreciated. Just another pair of eyes might solve the problem. Maybe I am blind.
Basically the error is telling me that I cannot create customerService bean in my controller because the customerDao bean cannot be located and therefore cannot be injected into the service.
When I use Intellij I am able to follow the bean references and everything appears
to be wired up correctly but when I run in tomcat6 or tomcat7 get the following errors:
Sep 26, 2013 10:13:02 AM org.springframework.web.context.ContextLoader initWebApplicationContext
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'customerService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mydomain.dao.CustomerDao com.mydomain.service.CustomerService.customerDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mydomain.dao.CustomerDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1122)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4701)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5204)
at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5199)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.mydomain.dao.CustomerDao com.mydomain.service.CustomerService.customerDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mydomain.dao.CustomerDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
... 21 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.mydomain.dao.CustomerDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:986)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:856)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:768)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
... 23 more
Sep 26, 2013 10:13:02 AM org.apache.catalina.core.StandardContext startInternal
Code as follows:
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mydomain.config.WebConfig</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mydomain.config.WebConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
WebConfig.java
package com.mydomain.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
#EnableWebMvc
#Configuration
#Import({DaoConfig.class, ServiceConfig.class, ControllerConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public Validator getValidator(){
return new LocalValidatorFactoryBean();
}
#Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
DaoConfig.java
package com.mydomain.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#ComponentScan({"com.mydomain.dao", "com.mydomain.service"})
public class DaoConfig {
#Bean
public LocalSessionFactoryBean getSessionFactory(){
final LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(getDataSource());
sessionFactoryBean.setPackagesToScan(new String[]{"com.mydomain.domain"});
sessionFactoryBean.setHibernateProperties(hibernateProperties());
return sessionFactoryBean;
}
#Bean
public DataSource getDataSource(){
final DriverManagerDataSource dmds = new DriverManagerDataSource();
dmds.setDriverClassName("com.mysql.jdbc.Driver");
dmds.setUsername("root");
dmds.setPassword("");
dmds.setUrl("jdbc:mysql://localhost/commandsearch");
return dmds;
}
#Bean
public HibernateTransactionManager transactionManager() {
final HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(getSessionFactory().getObject());
return txManager;
}
#Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.hbm2ddl.auto", "update");
setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
setProperty("hibernate.show_sql", "true");
}
};
}
}
IAbstractDao.java
package com.mydomain.dao;
import java.io.Serializable;
import java.util.List;
public interface IAbstractDao <T extends Serializable> {
T findOne(final long id);
List<T> findAll();
void save(final T t);
void delete(final T t);
void deleteById(final long id);
}
AbstractHibernateDao.java
package com.mydomain.dao;
import java.io.Serializable;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
public class AbstractHibernateDao<T extends Serializable> implements IAbstractDao<T> {
protected Class<T> entityClass;
protected final Log logger = LogFactory.getLog(getClass());
protected AbstractHibernateDao(Class<T> entityClass){
this.entityClass = entityClass;
}
#Autowired
private SessionFactory sessionFactory;
protected final Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
#Override
public T findOne(final long id) {
return ((T) getCurrentSession().get(entityClass, id));
}
#Override
public List<T> findAll() {
return (List<T>)getCurrentSession().createQuery("from " + entityClass.getName()).list();
}
#Override
public void save(final T t) {
getCurrentSession().saveOrUpdate(t);
}
#Override
public void delete(final T t) {
getCurrentSession().delete(t);
}
#Override
public void deleteById(final long id) {
final T entity = findOne(id);
delete(entity);
}
}
CustomerDao.java
package com.mydomain.dao;
import org.springframework.stereotype.Repository;
import com.mydomain.domain.Customer;
#Repository
public class CustomerDao extends AbstractHibernateDao<Customer> {
public CustomerDao(){
this(Customer.class);
}
public CustomerDao(Class<Customer> entityClass){
super(entityClass);
}
}
ServiceConfig.java
package com.mydomain.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan({"com.mydomain.service"})
public class ServiceConfig {
}
AbstractService.java
package com.mydomain.service;
import java.io.Serializable;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.annotation.Transactional;
import com.mydomain.dao.IAbstractDao;
#Transactional
public abstract class AbstractService<T extends Serializable> {
protected final Log logger = LogFactory.getLog(getClass());
public T findOne(final long id) {
return getDao().findOne(id);
}
public List<T> findAll() {
return getDao().findAll();
}
public void save(final T entity) {
getDao().save(entity);
}
public void delete(final T entity) {
getDao().delete(entity);
}
public void deleteById(final long entityId) {
getDao().deleteById(entityId);
}
protected abstract IAbstractDao<T> getDao();
}
CustomerService.java
package com.mydomain.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.mydomain.dao.CustomerDao;
import com.mydomain.dao.IAbstractDao;
import com.mydomain.domain.Customer;
#Service
#Transactional
public class CustomerService extends AbstractService<Customer>{
#Autowired
private CustomerDao customerDao;
#Override
protected IAbstractDao<Customer> getDao() {
return customerDao;
}
}
Your immediate problem is this
package com.mydomain.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#Configuration
#ComponentScan({"com.mydomain.service"})
public class ServiceConfig {
}
You're scanning your #Service class but you have nothing in that context that gives you a CustomerDao bean available for injection so it fails with the exception you have.
There are a bunch of other things wrong with your configuration. Your DaoConfig scans both dao and service packages. This on its own is not bad, but you have all the other XConfig classes that are redundant.
Also, your web.xml configuration is going to create 2 WebConfig contexts, one for the DispatcherServlet and one for the ContextLoaderListener.
Your ContextLoaderListener should load the root context and the DispatcherServlet should load the servlet context.
For example, the DispatcherServlet should load the WebConfig as such
#EnableWebMvc
#Configuration
#Import(ControllerConfig.class)
public class WebConfig extends WebMvcConfigurerAdapter {
Note it only #Imports ControllerConfig.
Your ContextLoaderListener should load the application config as such
#Configuration
#EnableTransactionManagement
#ComponentScan({"com.mydomain.dao", "com.mydomain.service"}, ...)
public class ApplicationConfig {
// all the #Bean methods from each of your other XxxConfig classes
}
If you want to modularize it further, keep in mind that #Import only works on the #Configuration class or context that is using it, not on the context being imported.

Resources