Spring Data JDBC UnsatisfiedDependencyException - spring-boot

I wanted to move from JdbcTemplate to Spring Data JDBC. However I seem to have some misconfiguration but I cannot figure out where. The errors are "expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}" and "Parameter 0 of constructor ... required a bean ... that could not be found."
I put #Repository on the public repository interfaces extending PagingAndSortingRepository (as I did with the DAO classes extending from JdbcDaoSupport) without success. Then I added #EnableJdbcRepositories with and without package name to the database config class, also no success. I also tried the database config to inherit from AbstractJdbcConfiguration, still the same errors ...
Unfortunately I couldn't find a working example and I now gave up after some trial and error. I still would love to get this working, the version I used is spring-boot-starter-data-jdbc:2.4.0
Code fragments:
DatabaseConfiguration.java
#Configuration
#EnableJdbcRepositories("<basepackage>.repository.jdbc")
#EnableJdbcAuditing(auditorAwareRef = "springSecurityAuditorAware")
#EnableJpaRepositories("<basepackage>.repository")
#EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
#EnableTransactionManagement
#EnableElasticsearchRepositories("<basepackage>.repository.search")
public class DatabaseConfiguration extends AbstractJdbcConfiguration {
}
UserRepository.java
#Repository
public interface UserRepository extends PagingAndSortingRepository<User, String> {
}
QualityResource.java (REST Controller)
public QualityResource(UserRepository userRepository) {
this.userRepository = userRepository;
}
Error messages:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'qualityResource' defined in file [.../backend/build/classes/java/main/.../web/rest/QualityResource.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '....repository.jdbc.UserRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Application failed to start: Description: Parameter 0 of constructor in <basepackage>.web.rest.QualityResource required a bean of type '<basepackage>.repository.jdbc.UserRepository' that could not be found.

Related

NoBean found exception

**I am getting below error even though i have down the #autowired .please some one let me know why this issue happening its a ant build with spring config
utor.
2022-07-08 10:18:09,856 WARN org.springframework.context.support.
ClassPathXmlApplicationContext - Exception encountered during context initialization
cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'delegateProcessor':
Unsatisfied dependency expressed through field 'headerProcessor';
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean found for dependency
[org.springframework.batch.item.ItemProcessor<com.abc.proj.model.FileHeader,
com.abc.proj.model.FileHeader>]:
expected at least 1 bean which qualifies as autowire candidate.
Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true),
#org.springframework.beans.factory.annotation.Qualifier(value=headerProcessor)}
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'delegateProcessor': Unsatisfied dependency expressed
through field 'headerProcessor';
nested exception is org.springframework.beans.factory.
NoSuchBeanDefinitionException: No qualifying bean found for dependency
[org.springframework.batch.item.ItemProcessor<com.abc.proj.model.FileHeader,
com.abc.proj.model.FileHeader>]: expected at least 1 bean which qualifies as
autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true),
#org.springframework.beans.factory.annotation.Qualifier(value=headerProcessor)}
#Component
public class DelegateProcessor implements ItemProcessor<Object, Object>, InitializingBean {
#Autowired
#Qualifier("headerProcessor")
private ItemProcessor<FileHeader, FileHeader> headerProcessor;
#Autowired
#Qualifier("detailProcessor")
private ItemProcessor<FileDetail, FileDetail> detailProcessor;
#Autowired
#Qualifier("trailerProcessor")
private ItemProcessor<FileTrailer, FileTrailer> trailerProcessor;
#Component
public class HeaderProcessor implements ItemProcessor<Object, Object>{
#Autowired
private HeaderValidatorDao headerValidatorDao ;**
With a configuration class you could initialize your beans manually, specially if they need custom names.
#Configuration
public class MyCustomConfiguration {
#Bean(name ="headerProcessor")
public ItemProcessor<FileHeader, FileHeader> headerProcessorBean() {
ItemProcessor<FileHeader, FileHeader> myBean = new HeaderProcessor<>();
//Do whaterever you need to initilize your bean
return myBean;
}
#Bean(name ="detailProcessor")
public ItemProcessor<FileDetail, FileDetail> detailProcessorBean() {
ItemProcessor<FileDetail, FileDetail> myBean = new ItemProcessor<>();
//Do whaterever you need to initilize your bean
return myBean;
}
}
In this way these beans will be available for autowiring.

#ConditionalOnBean not work for spring boot test

Hy everyone! I'm trying to solve the problem for a very long time.
There is very simple spring boot test
public class ApplicationTest {
#Test
void testContext() {
SpringApplication.run(Application.class);
}
}
And several beans...
#Service
#ConditionalOnBean(CommonService.class)
#RequiredArgsConstructor
public class SimpleHelper {
...
#Service
#RequiredArgsConstructor
#ConditionalOnBean(CommonFeignClient.class)
public class CommonService {
...
#FeignClient(
name = "CommonClient",
url = "localhost:8080"
)
public interface CommonFeignClient {
And the main class look as
#SpringBootApplication
#EnableFeignClients(clients = AnotherFeignClient.class)
public class Application {
When the spring application starts everything works ok. SimpleHelper does not created.
But in the spring boot test throw the exception:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'simpleHelper' defined in URL [...]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'foo.bar.CommonService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
Please help, I don't understand what's going on anymore =)
Spring boot version is 2.3.0.RELEASE.
To use #ConditionalOnBean correctly, CommonService needs to be an auto-configuration class or defined as a bean by an auto-configured class rather than a service that's found by component scanning. This ensures that the bean on which CommonService is conditional has been defined before the condition is evaluated. The need for this is described in the annotation's javadoc:
The condition can only match the bean definitions that have been processed by the application context so far and, as such, it is strongly recommended to use this condition on auto-configuration classes only. If a candidate bean may be created by another auto-configuration, make sure that the one using this condition runs after.

Unit Test - No qualifying bean of type ERROR

I am trying to unit test my rest api controller. Controller code is as below
#RestController
#RequestMapping("/events")
public class EventController {
#Autowired
private EventService eventService;
#GetMapping
public Iterable<Event> getEvents(EventSearchFilter filter, #PageableDefault(page = 1, size = 5, sort = "location.city, asc") Pageable pageable) {
return eventService.findEventsOnCondition(filter, pageable);
}
...
}
Test class is
#RunWith(SpringRunner.class)
#WebMvcTest(EventController.class)
public class EventEndpointTest {
private MockMvc mockMvc;
#InjectMocks
private EventController eventController;
#Mock
private EventService eventService;
#InjectMocks
private PageableHandlerMethodArgumentResolver pageableArgumentResolver;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(eventController).setCustomArgumentResolvers(pageableArgumentResolver).build();
}
#Test
public void getEvents() throws Exception{
Event event = new Event();
event.setName("TestName");
EventSearchFilter filter = new EventSearchFilter();
filter.setName("TestName");
List<Event> eventList = singletonList(event);
given(eventController.getEvents(any(EventSearchFilter.class), any(PageRequest.class))).willReturn(eventList);
mockMvc.perform(get("/events")
.contentType(APPLICATION_JSON))
.andExpect(status().isOk());
}
...
}
However, I got error complaining saying I have Error creating bean with name 'eventController':
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'EventService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}.
As I got above error, I tried use Autowired annotation for my EventService. It still doesn't work. any ideas? Thanks.
I found a solution. All I need to do is replacing #WebMvcTest(EventController.class) in my Test class to #SpringBootTest(classes = Application.class). Thanks guys.
Did you declare #Service annotation at EventService?
#Service
public class EventService {
...something code..
}
I guess Spring cannot find bean named EventService
I had a similar issue where the stack trace showed
java.lang.IllegalStateException: Failed to load ApplicationContext
...
...
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'Controller': Unsatisfied dependency expressed through field 'i18NService';
...
...
...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type '...Service' available:
...
...
...
and ultimately the solution was that the services needed to be mocked with #MockBean since regular components (including services and repositories) will not be scanned.
Same answer with #DFeng. Encountered the below error:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mysqlRedisCachingController': Unsatisfied dependency expressed through field 'mysqlRedisBusinessService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mysqlRedisBusinessService': Unsatisfied dependency expressed through field 'mysqlRedisService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mysqlRedisService': Unsatisfied dependency expressed through field 'mysqlRedisRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.caching.redismanager.repo.MysqlRedisRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.example.caching.redismanager.repo.MysqlRedisRepository' in your configuration.
This annotation did the trick.
#MockBean
Added the below in the Test Class:
#MockBean
private MysqlRedisRepository mysqlRedisRepository;
#Test
void contextLoads() {}
It works as expected. Hope this helps.

Spring NoSuchBeanDefinitionException when wiring a #Component with value defined

My component is defined as below
#Component("myBo")
public class MyBO {
#Autowired
JpaRepository<MyData, Long> repository;
Spring Data Interface:
public interface MyDataRepository extends JpaRepository<MyData, Long> {
Entitymanager definition:
#Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory( EntityManagerFactoryBuilder builder, #Qualifier("dmDs") final DataSource dmDs) {
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = builder.dataSource(dmDs).packages(new String[]{"my.packages"}).build();
return localContainerEntityManagerFactoryBean;
}
and my test fails with this error
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myBO': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.jpa.repository.JpaRepository<MyData, java.lang.Long>' 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:588)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.jpa.repository.JpaRepository<MyData, java.lang.Long>' available: expected at least 1 bean which qualifies as autowire candidate.
whereas the following works fine. Need help in understanding this behavior.
#Component
public class MyBO {
#Autowired
JpaRepository<MyData, Long> repository;
Thanks
You should not autowire JpaRepository<MyData, Long> as is. You should extend it and create your own interface as follows.
public interface MyRepository extends JpaRepository<MyData, Long> {
}
The reason you won't be able to autowire JpaRepository directly is because it is annotated with NoRepositoryBean annotation and that prevents creating an instance of it. It is always recommended to extend the base repo classes and create your own interfaces.
P.S: Do not forget to enable Jpa Repositories on these repo interfaces you are going to create. Otherwise you won't be able to autowire them.
Similar to this in your xml config.
<jpa:repositories base-package="com.acme.repositories"/>

struts2 + spring4 + mybatis3 if use #Transactional will be a mistake (Autowired(required=true))

I am using spring #Transactional to manage MySQL transactional.
But the way I add #Transactional is wrong.
#Service
//#Transactional(readOnly = true)
public class UserInfoService extends BaseService
#Autowired
private UserInfoAccessor userInfoAccessor;
//#Transactional
public void insert()
Map<String, String> map = new HashMap<>();
map.put("userName", "test");
userInfoAccessor.insert(map);
The error message I receive is:
Unable to instantiate Action, com.luotuo.xiaobao.action.IndexAction, defined for 'index' in namespace '/'Error creating bean with name 'com.luotuo.xiaobao.action.IndexAction': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.luotuo.xiaobao.service.UserInfoService com.luotuo.xiaobao.action.IndexAction.userInfoService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.luotuo.xiaobao.service.UserInfoService] 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)
You can download my project source here.
What is the correct way to set this up?

Resources