#Autowired not working for interface - spring

I am trying all the solutions from Google from last 4 days. but not working.
I am trying to autowire below Interface -
#Qualifier("roleAccessRepository")
#Repository
public interface RoleAccessRepository extends BaseJPACrudRepository<RoleAccess, Long> {
in PermissionEvaluator in following way.But its not working.
#Scope(proxyMode = ScopedProxyMode.INTERFACES, value = "prototype")
public class PermissionEvaluator implements org.springframework.security.access.PermissionEvaluator
{
#Autowired
RoleAccessRepository roleAccessRepository;
..........
Giving me error -
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: net.pa
ger.lrs.sql.db.RoleAccessRepository net.pager.lrs.security.PermissionEvaluator.roleAccessRepository;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying
bean of type [net.pager.lrs.sql.db.RoleAccessRepository] found for dependency: expected at least 1 b
ean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springf
But Repository defined in the same package and autowired in service class are working good.
#Service
#Transactional
public class AccountService extends BaseCrudService<Account> {
/** The account db. */
#Autowired
private AccountRepository accountDB;
}
My security.xml is as follows - which has base package net.pager.lrs which is parent directory.
<bean id="permissionEvaluator" class="net.pager.lrs.security.PermissionEvaluator">
<constructor-arg index="0">
Please help me.

Ok,
From the discussions above, I still think that the problem is with not having the concrete implementation of the Autowired interfaces. Just for the sake of common sense, if you do not provide an implementation, what will you execute using the reference of the Autowired interface.
There is a way where you do not define the implementation, spring can generate proxy beans and autowire, but that is of no use.
You might end up providing an anonymous implementation of the interface as well.

Related

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.

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

BeanCurrentlyInCreationException when spring starts

I am getting the BeanCurrentlyInCreationException when I start my spring application.
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.datayes.bdb.rrp.business.service.impl.StockModelBaseService com.datayes.bdb.rrp.business.service.impl.StockModelV3ServiceImpl.stockModelBaseService; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'stockModelBaseService': Bean with name 'stockModelBaseService' has been injected into other beans [researchFrameworkCommonServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:561)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
... 71 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'stockModelBaseService': Bean with name 'stockModelBaseService' has been injected into other beans [researchFrameworkCommonServiceImpl] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:568)
And here are the code snippets I have found caused this issue:
#Component public class KafkaConsumerServer implements MessageListener<String, String> {
#Autowired StockModelV3Service stockModelV3Service;
#Autowired FinanceIndicatorService financeIndicatorService;
......
}
#Service public class FinanceIndicatorServiceImpl implements FinanceIndicatorService {
#Autowired StockModelV3Service stockModelV3Service;
#Autowired IndustryResearchFrameworkService industryResearchFrameworkService;
......
}
#Service public class IndustryResearchFrameworkServiceImpl implements IndustryResearchFrameworkService {
#Autowired ResearchFrameworkCommonService commonService;
......
}
#Service public class ResearchFrameworkCommonServiceImpl implements ResearchFrameworkCommonService {
#Autowired StockModelBaseService stockModelBaseService;
......
}
I found some thing interesting in the following article may have explained why.
https://blog.imaginea.com/spring-bean-creation-is-not-thread-safe/
As both my StockModelV3Service and FinanceIndicatorService depends on stockModelBaseService(FinanceIndicatorService -> industryResearchFrameworkService -> researchFrameworkCommonService -> stockModelBaseService), during spring bean creation, they have raced against each other. Which caused BeanCurrentlyInCreationException. As the above article noted, spring bean creation is not thread safe.
To solve this problem seems easy. I changed autowire order as below:
public class KafkaConsumerServer implements MessageListener<String, String> {
#Autowired FinanceIndicatorService financeIndicatorService;
#Autowired StockModelV3Service stockModelV3Service;
As FinanceIndicatorService also depends on StockModelV3Service, so when financeIndicatorService is loaded, it will wait till stockModelV3Service is loaded then load itself. Thus avoid BeanCurrentlyInCreationException.
After all, it has nothing to do with circular reference. As StockModelBaseService doesn't depends on other services.

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"/>

Can't Autowire ServletContext

I'm new with Spring, and I'm trying to use the #Autowire annotation for the ServletContext with my class attribute:
#Controller
public class ServicesImpl implements Services{
#Autowired
ServletContext context;
I defined the bean for this class in my dispatcher-servlet.xml:
<bean id="services" class="com.xxx.yyy.ServicesImpl" />
But when I try to run a JUnit test it gives the following error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [javax.servlet.ServletContext] 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)}
I thought that the ServletContext injection was automatic with spring... How can I solve this?
Thanks!
EDIT: I want to use the servletContext to call the getRealPath() method. Is there any alternative?
Implement the ServletContextAware interface and Spring will inject it for you
#Controller
public class ServicesImpl implements Services, ServletContextAware{
private ServletContext context;
public void setServletContext(ServletContext servletContext) {
this.context = servletContext;
}
You'll probably want to take a look at MockServletContext which can be used in unit tests.
ServletContext is not a Spring bean and it can, therefore, not be injected unless you implement ServletContextAware.
If one thinks in modules or layers then the servlet context shouldn't be available outside the web module/layer. I suppose your ServicesImpl forms part of the business or service layer.
If you gave a little more context we might be able to suggest better alternatives.

Resources