BeanCreationException for Spring-data-jpa repository in controller - spring

I have spring-boot-starter-data-jpa and spring-boot-starter-web. I try load List<Project> from mysql using Spring jpa but get bellow BeanCreationException in controller.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'controller': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.project.data.spring_jpa.ProjectRepository com.project.application.Controller.repository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.project.data.spring_jpa.ProjectRepository] 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)}
Controller.java:
...
#RestController
public class Controller {
...
#Autowired
private ProjectRepository repository;
private ProjectAccessor projectAccessor = manager.createAccessor(ProjectAccessor.class);
public void setRepository(ProjectRepository repository){
this.repository = repository;
}
#RequestMapping("/test")
#ResponseBody
public List<Project> test() {
System.out.println("mysql test");
return repository.findAll();
}
...
ProjectRepository.java:
public interface ProjectRepository extends CrudRepository<Project, Long>{
List<Project> findAll();
}

Did you write #Repository annotation on ProjectRepository
#Repository
public interface ProjectRepository extends CrudRepository<Project, Long>{
List<Project> findAll();
}
Do make sure you enabled JpaRepository on your configuration using #EnableJpaRepositories

We get this exception usually when we don't specify where to look for the JPA repositories.
So mention #EnableJpaRepositories("your repository package") where you specify #Configuration or #SpringBootApplication.
It will work fine.

Related

Test application cannot find autowired bean in same project

I have a jar file that is the persistence layer, ad I just want to test the DAO that are simply autowired into other service layer clasees. But I want to test without any mocking or whatever.
I think this should be pretty simple. I have this in my srs/test/java
#RunWith(SpringRunner.class)
#ComponentScan("com.xxxx")
public class ApplicationTester {
#Autowired
AplicationDocumentDao aplicationDocumentDao;
#Test
private void testAplicationDocumentDao() {
aplicationDocumentDao.allForOrg(1);
}
}
All the DAO's are in the same projust under the usual /src/main/java
When I run the mvn to just run the tests like this:
mvn -Dtest=ApplicationTester test
I get this error:
Error creating bean with name 'xxx.test.ApplicationTester': Unsatisfied dependency expressed through field 'aplicationDocumentDao';
nested exception is 0rg.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'xxx.dao.AplicationDocumentDao' available:
expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
Which means is can't find the Bean of course, but i would think the #ComponentScan would pick up add the Dao's.
How do I get this tester to find all my Dao's (Which are all annotated with #Componenet) and are picked up just fine in the rest for the application.
Any ideas?
** EDIT **
here is the DAO
#Repository
#Component
public class AplicationDocumentDao extends JdbcDaoSupport {
#Autowired
public void setJT(JdbcTemplate jdbcTemplate) {
setJdbcTemplate(jdbcTemplate);
}
public List<ApplicationDocumentBean> allForOrg(int orgId) {
String sql = "SELECT * FROM ApplicationDocument WHERE organizationId = ?";
return (List<ApplicationDocumentBean>) getJdbcTemplate().query(sql, new BeanPropertyRowMapper<ApplicationDocumentBean>(ApplicationDocumentBean.class), orgId);
}
}
Add annotate to your persistence layer class, for example: #Repository or #Component,like this :
#Repository
public interface OrderMapper {}

Spring Boot + Groovy + JPA, failed to inject JpaRepository

Here is my app.groovy code:
package org.test
import javax.persistence.*
import org.springframework.data.jpa.repository.JpaRepository
#Grab('spring-boot-starter-data-jpa')
#Grab('mysql-connector-java')
#Entity
#Table (name="owner")
class Owner {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
Long ownerId;
#Column(name = 'Name')
String name;
#Column(name = 'DateOfBirth')
Date dateOfBirth;
#Column(name = 'Address')
String address;
#Override
String toString() {
return String.format(
"Owner[id=%d, Name='%s', DateOfBirth='%s']",
id, name, dateOfBirth);
}
}
interface OwnerRepository extends JpaRepository<Owner, Long> {
List<Owner> findByName(String name);
}
class Runner implements CommandLineRunner {
#Autowired
private DataSource ds;
#Autowired
private OwnerRepository repository
void run(String... args) {
for (owner in repository.findAll()) {
println owner
}
}
}
application.properties code:
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/ng4
spring.datasource.username=user_name
spring.datasource.password=********
spring.jpa.show-sql=false
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
spring.jpa.database=MYSQL
spring.jpa.hibernate.ddl-auto=validate
After running $ spring run app.groovy, I got following error messages:
Field repository in org.test.Runner required a bean of type 'org.test.OwnerRepository' that could not be found.
Action:
Consider defining a bean of type 'org.test.OwnerRepository' in your configuration.
...
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'runner': Unsatisfied dependency expressed through field 'repository'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type 'org.test.OwnerRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
I have tried to test inject JdbcTemplate using the same code statement, and it works fine, so I have no idea what's wrong in those code.
Please give me some suggestions, thanks very much !!
Actually the problem is that you also don't have #SpringBootApplication on top of your Runner class.
you're missing #Repository annotation on top of your OwnerRepository. That might be it.

Autowiring not working in SpringBoot controller

Hi i was trying to work over an existing SpringBoot application. I created a service class and tried to autowire it in the existing controller, but when trying to build, its failing saying bean injection failed.
Cause: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'controller': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private
com.disooza.www.card.dispenser.service.FilaPartnerService
com.disooza.www.card.dispenser.controller.CardDispenserController.FilaPartnerService;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[com.disooza.www.card.dispenser.service.FilaPartnerService] 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:334)
Following is my controller class:
#Controller
#RequestMapping(value = "/service")
public class CardController {
private static final Logger LOGGER = LoggerFactory.getLogger(CardController.class);
#Autowired
private CardDao dao;
#Autowired
private PaymentService paymentService;
#Autowired
private FilaPartnerService filaPartnerService;
FilaPartnerService is the newly created interface, and rest all autowires are working fine in this controller.
Interesting thing is when I try to place this service class in any other controller it is working fine. Any help over this issue will be appreciated, since I'm stuck with it.
This is my service interface:
#Service
public interface FilaPartnerService {
RetrievePaymentTokenResponse retrieveXXX(SupplierRequest request);
}
This is the implementation class:
#Component
public class FilaPartnerServiceImpl implements FilaPartnerService {
#Autowired
private RestTemplate restTemplate;
#Autowired
private RetrieveRequestBuilder retrieveRequestBuilder;
#Value("${filaPartner.url}")
private String filaServiceUrl;
#Override
public RetrievePaymentTokenResponse retrieveFilaPaymentToken(SupplierTokenRequest request) {
RetrievePaymentTokenResponse tokenResponse = null;
RetrievePaymentTokenRequest paymentServiceRequest = retrievePaymentTokenRequestBuilder.retrievePaymentTokenRequestBuilder(request);
try {
tokenResponse =
restTemplate.postForObject( FilaServiceUrl, paymentServiceRequest, RetrievePaymentTokenResponse.class);
} catch (RestClientException exp) {
//TO-DO return error code
}
return null;
}
}

Spring Injecting implementation instead of interface

Here my class structure :
public interface CertificatService
{
}
The only one implementation
#Service
#Transactional
public class CertificatServiceImpl extends GestionCertificat implements CertificatService
{
}
And the injection :
#Service
#Transactional
public class ConnexionEbicsServiceImpl extends GestionConnexion implements ConnexionEbicsService
{
#Inject
private CertificatServiceImpl certificatService;
}
}
Injection the implementation causes injection failure :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'connexionEbicsServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tess2i.service.impl.CertificatServiceImpl com.tess2i.service.impl.ConnexionEbicsServiceImpl.certificatService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.tess2i.service.impl.CertificatServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#javax.inject.Inject()}
But if I inject the interface, it works :
#Service
#Transactional
public class ConnexionEbicsServiceImpl extends GestionConnexion implements ConnexionEbicsService
{
#Inject
private CertificatService certificatService;
}
}
But I need to inject the implementation so to benefit methods inherited from GestionCertificat
Can you help me to autowired the implementation. I understand that the real type is a proxy and not the implementation class CertificatServiceImpl as I would like. But what is the solution so ?
Thanks.
Perfect.
Just using proxy via CGLIB it is OK setting proxyTargetClass = true :
#EnableTransactionManagement(proxyTargetClass = true)
Thanks for the answer here : Spring - how to inject concrete interface implementation?

Spring Autowiring failing when using Cobertura

When I run Cobertura, it causes the following Spring autowiring error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService; nested exception is java.lang.IllegalArgumentException: Can not set com.dnb.components.storage.service.UserService field com.dnb.components.storage.rest.resource.UserResource.userService to com.sun.proxy.$Proxy56 at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
As suggested in other related posts, I tried forcing Spring to use CGLIB by changing "proxyTargetClass=true", but this results in a different error:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userResource': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.dnb.components.storage.service.UserService com.dnb.components.storage.rest.resource.UserResource.userService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.dnb.components.storage.repository.UserRepository com.dnb.components.storage.service.UserService.repository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Post-processing of the FactoryBean's object failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.sun.proxy.$Proxy54]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy54
This is what the Repository class looks like:
#Transactional
public interface UserRepository extends CrudRepository<User, Long> {
public User findByCrmId(String crmIdId);
}
Here is the service that gets injected with UserRepository:
#Service
#Transactional
public class UserService extends TraceablePersistenceService<User, UserRepository> {
#Autowired
UserRepository repository;
#Transactional
public Iterable<User> findAll() {
return repository.findAll();
}
public User findOne(Long id) {
return repository.findOne(id);
}
}
Our configuration is in
#Configuration
#EnableTransactionManagement(proxyTargetClass=true)
#EnableJpaRepositories(basePackages = {"com.dnb.components.storage.repository"})
#Profile("inmemory")
public class InMemoryStandaloneStorageConfig extends BasicJpaStorageConfig {
....
(omitted for brevity)
UserResource.java:
#Component
#Path(UserResource.uri)
public class UserResource extends AbstractResource {
public final static String uri = BASE_URI + "/users";
#Override
public String getURI() {
return BASE_URI + uri;
}
#Autowired
private UserService userService;
...
It seems that the Spring Data JPA generated Repository class cannot be proxied either way without screwing up the auto-wiring.
Is there a fix for this? Is it even a good idea to annotate Repository methods with #Transactional? Should the annotation be at the service level only?
usually, we do not inject concrete classes but we inject interfaces.
this is my suggestion.
a. refactor UserService to UserServiceImpl class
b. create UserService interface
c. UserServiceImpl implements UserService
d. add "findAll" and "findOne" method declaration to UserService interface

Resources