Spring JPA not implementing/autowiring repository despite #EnableJpaRepositories annotation - spring

I'm getting an exception when I start my application, where Spring complain about UnsatisfiedDependencyException:
Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'applicationConfig': Unsatisfied dependency expressed through field 'controlRepository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.oak.api.finance.repository.ControlRepository]: 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:569)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
My application is organized in this format:
I declared my repository interfaces, with the proper Spring JPA annotations:
#RepositoryRestResource(collectionResourceRel = "exchange", path = "exchanges")
public interface ControlRepository extends PagingAndSortingRepository<Control, Long> {
}
I annotated the EntryPoint class that contains the main method
#SpringBootApplication
#EntityScan(basePackages = {"com.oak.api.finance.model.dto"})
#EnableJpaRepositories(basePackages = {"com.oak.api.finance.repository"})
public class EntryPoint {
public static void main(String[] args) {
Logger logger = LogManager.getLogger(EntryPoint.class);
logger.info("Starting application");
ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
// SpringApplication.run(EntryPoint.class, args);
ctx.getBean(ApplicationServer.class).start();
}
I used #Autowired to inject my repository into my spring config (java based) ApplicationConfig class:
#Autowired
private ControlRepository controlRepository;
#Autowired
private CompanyRepository companyRepository;
#Autowired
private SectorRepository sectorRepository;
Essentially I want to control the dependency on Spring and limit it to a couple of packages, (the repositories, the java config, and the program entry point - EntryPoint)
I assumed that, by specifying #EnableJpaRepositories with the package where my repositories are located, spring would create a proxy for my repository and instantiate an instance of that, and that by the time I call :
ApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class)
The repositories instances would be present in the beans poole and would be possible to autowire them into my ApplicationConfig context, and then inject them into my controller.
This is clearly not happening, and Spring is complaining about the missing Bean to autowire, but I'm not sure what am I missing.
Below a snapshot of my packages:
any ideas?

My guess is your repositories are not being scanned, so as a result beans are not getting created. Can you try removing these 2 annotations
#EntityScan(basePackages = {"com.oak.api.finance.model.dto"})
#EnableJpaRepositories(basePackages = {"com.oak.api.finance.repository"})
And keep only #SpringBootApplication. If this is not working, you might need to check the package structure (if possible paste a screenshot here)
Edit 1
replace #SpringBootApplication with
#Configuration
#EnableAutoConfiguration
#ComponentScan("com.oak")
Edit2
Use
new SpringApplicationBuilder()
.sources(SpringBootApp.class)
.web(false)
.run(args);
Or use CommandLineRunner after changing ComponentScan path to "com.oak" as mh-dev suggested

Related

#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.

Spring Data JDBC UnsatisfiedDependencyException

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.

No qualifying bean of type 'ThreadPoolTaskExecutor' available

I'm using Spring Boot 2.2.4 and I'm trying to a custom Executor
Below are the relevant classes
#Configuration
#ManagedResource
public class ExecutorConfig {
#Bean(name = "detailsScraperExecutor")
public Executor getDetailsAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setQueueCapacity(1000000);
executor.setThreadNamePrefix("detailsScraperExecutor-");
executor.initialize();
return executor;
}
}
and the following class which tries to use it.
#Component
#Profile("!test")
public class DetailsScraper {
private static final Logger logger = LoggerFactory.getLogger(DetailsScraper.class);
#Autowired
#Qualifier("detailsScraperExecutor")
private ThreadPoolTaskExecutor detailsScraperExecutor;
}
When I run the application I get the following error
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'detailsScraper': Unsatisfied dependency
expressed through field 'detailsScraperExecutor'; nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor'
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.annotation.Qualifier(value="detailsScraperExecutor")}
my application.properties
spring.jmx.enabled=false
spring.datasource.url=jdbc:postgresql://example.com:5432/example
spring.datasource.username=example
spring.datasource.password=password
spring.jpa.open-in-view=false
logging.level.com.gargoylesoftware.htmlunit=ERROR
spring.datasource.hikari.maximumPoolSize = 30
app.properties.parseaddress.endpoint=http://example.com
Even though I have named it detailsScraperExecutor Spring can't find it? Why is that?
You need to inject the same type of class as declared in configuration but not a higher-level one. But you can use the lower-level one.
#Autowired
private Executor detailsScraperExecutor;

JAR SPRING #autowired

I create a java archive and i would like integrate this on my application.
on my principal application :
ApplicationContext.xml :
<context:component-scan base-package="com.test.chomage" />
ChomageController.java :
#Controller
#Path("/chomage")
public class ChomageController {
#Autowired
ChomageService chomageService;
#Autowired
OrganisationService organisationService;
}
On my java archive :
appConfig.java
#Configuration
#ComponentScan("com.test.jarPatrimoine")
public class AppConfig {
}
OrganisationService.java
public interface OrganisationService {
//Functions
}
OrganisationServiceImpl.java
#Service
#Transactional
public class OrganisationServiceImpl implements OrganisationService
//Functions
}
When i start my tomcat server, i have the next error :
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'chomageController':
Unsatisfied dependency expressed through field 'organisationService';
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type
'com.test.jarPatrimoine.service.OrganisationService' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency
annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
Can you help me ?
Thanks
Spring is looking for com.vnf.jarPatrimoine.service.OrganisationService, but scan is configured as #ComponentScan("com.test.jarPatrimoine"). You might have to change it.
Are there any other classes implementing OrganisationService? If so you need to add #Qualifier annotation to inject the right implementation.
#Autowire
#Qualifier("thequalifyingbean")
OrganisationService organisationService;
also use #Controller for your controller class instead of #Component

Spring-boot with Liquibase Overloading Property

I am using Spring boot and Liquibase.
Using this url as guidelines
http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/
In pom.xml, the below entry is present so that spring boot knows about liquibase.
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
and put the changelog file in resources folder.
db.changelog-master.xml
Now Spring boot first tring to find db.changelog-master.yaml in classpath and throwing the exception like this.
Cannot find changelog location: class path resource [db/changelog/db.changelog-master.yaml
To Fix the Issue, I have added the bean like below in my class and tried to set changeLog proprty.
#Configuration
#ComponentScan
#EnableAutoConfiguration
public class SampleDataJpaApplication {
#Autowired
LiquibaseProperties properties;
#Autowired
private DataSource dataSource;
#Bean
public SpringLiquibase liquibase() {
SpringLiquibase liquibase = new SpringLiquibase();
properties.setChangeLog("classpath:/db/changelog/db.changelog-master.xml");
liquibase.setChangeLog(this.properties.getChangeLog());
liquibase.setContexts(this.properties.getContexts());
liquibase.setDataSource(this.dataSource);
liquibase.setDefaultSchema(this.properties.getDefaultSchema());
liquibase.setDropFirst(this.properties.isDropFirst());
liquibase.setShouldRun(this.properties.isEnabled());
return liquibase;
}
public static void main(String[] args) throws Exception {
Logger logger = LoggerFactory.getLogger("SampleDataJpaApplication");
SpringApplication springApplication = new SpringApplication();
springApplication.run(SampleDataJpaApplication.class, args);
}
}
but it is failing with the message.
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'sampleDataJpaApplication': Injection of
autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field:
org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties
sample.data.jpa.SampleDataJpaApplication.properties; nested exception
is org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties]
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)}
Caused by: org.springframework.beans.factory.BeanCreationException:
Could not autowire field:
org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties
sample.data.jpa.SampleDataJpaApplication.properties; nested exception
is org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties]
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)}
Please provide the inputs here, why i am getting this exception or Is there any any other available way to override the same class so that i can change the changeLog property of liquibase properties.
I'm not entirely sure what the exact runtime path to your change log is, but why don't you just use the "liquibase.*" properties in application.properties? You should be able to leave out the Liquibase #Bean and let Boot do it for you.
If you prefer to add you own Liquibase #Bean then take the hint and make sure you define a LiquibaseProperties bean as well (e.g. by declaring #EnableConfigurationProperties(LiquibaseProperties.class)).

Resources