Can't inject repository in springboot - spring

This is my repository:
#Repository
public interface GroupRepository extends JpaRepository<Group, Integer> {}
This is how I tried to use it in my service class:
#Service
public class GroupService {
private final GroupRepository groupRepository;
#Autowired
public GroupService(GroupRepository groupRepository) {
this.groupRepository = groupRepository;
}
Got this error :org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'groupService' defined in file [/Users/nathanxuan/Files/Project/ratingApp/target/classes/com/xjy/service/GroupService.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'groupRepository' defined in com.xjy.mapper.GroupRepository defined in #EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Not a managed type: class com.xjy.pojo.Group
Does anyone know why this is happening? When I commented out the repository class everything works fine (I have another mapper class and that one also works).
-------edit-----------
This is the structure of my app:

I think the problem is with the model class Group, it needs the Entity annotation since you are using JPA. Try out this:
#Entity
#Data
#AllArgsConstructor
#NoArgsConstructor
public class Group {
....
}
Note: #Data #AllArgsConstructor #NoArgsConstructor comes from Lombok, so if you're not using it, just create regular Getter and Setter

Try removing #Repository from your repository. By extending from JpaRepository should be enough.
Unless you really need a setter injection defining your repository in the service like this should also be fine and more concise.
#Autowired
private GroupRepository groupRepository;

Related

Spring: Properly use of lombock Builder

I faced with problem while using of lombock #Builder.
In SpringBoot application I create the following component:
#Getter
#Builder
#Component
#AllArgsConstructor
public class ContentDTO {
private UUID uuid;
private ContentAction contentAction;
private String payload;
}
But when I run the application< I receive:
Error creating bean with name 'contentDTO': Unsatisfied dependency expressed through constructor parameter 0
Caused by:
No qualifying bean of type 'java.util.UUID' available: expected at least 1 bean which qualifies as autowire candidate
"Finger to the sky", I changed lombock-builder to custom builder, like this:
#Getter
#Component
public class ContentDTO {
private ContentDTO() {
}
// fields
public static Builder newBuilder() {
return new ContentDTO().new Builder();
}
public class Builder{
private Builder() {
private constructor
}
public ContentDTO build() {
return ContentDTO.this;
}
}
}
And problem is gone.
Its nice, but I clearly dont understand, what was problem!
Why in this case lombock-builder prevented the autowiring of beans?
And how to use lombock-builder properly in Spring ApplicationContext?
the use of the builder requires a default constructor. When you added the #AllArgsConstructor annotation the problem appears. therefore, you must also add the #NoArgsConstructor annotation. That should be the solution for your code.
Well ContentDTO has the #Component annotation therefore Spring tried to pick up and register an instance of ContentDTO in order to do so It tried to create an instance using all args constructor generated by Lombock since it was the only available constructor.
It failed due to it couldn't find registered beans with the given types expected by the ContentDTO constructor.
Adding #NoArgsConstructor or a default constructor without args like you did will work, the Builder is not related.

Scala with Spring: Constructor autowiring

I'm looking for "idiomatic" way to autowire Scala classes with Spring through constructor injection.
I've tried something like this:
#Component
class MyService #Autowired() ( val myDao: MyDao) extends Logging {
...
}
But I get an error:
Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [MyService]: No default constructor found; nested exception is java.lang.NoSuchMethodException: MyService.()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:964) ~[spring-beans-3.0.7.RELEASE.jar:3.0.7.RELEASE]
I've added support for #Autowired on the constructor of a Scala object into the spring-scala project. This is only (at time of writing) in the nightly snapshot.
This allows you to do
#Component
#Autowired
class Service(dep : Dependency) { }
https://github.com/spring-projects/spring-scala
We use this style for a Spring MVC app:
#Component
class MyService extends Logging {
#Autowired
private val myDao: MyDao = null
}

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

Spring expected at least 1 bean which qualifies as autowire candidate for this dependency

I have a trouble with this Autowire:
#Controller
public class ChiusuraController {
#Autowired
private ChiusuraProvider chiusuraProvider;
}
with this bean:
#Service #Transactional
public class ChiusuraProvider extends ThreadProvider {
public void run() {}
}
that extends
public abstract class ThreadProvider extends Thread implements InitializingBean, Runnable, DisposableBean {
...
}
I get this error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'chiusuraController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.cinebot.service.ChiusuraProvider com.cinebot.web.controller.ChiusuraController.chiusuraProvider; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.cinebot.service.ChiusuraProvider] 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 saw that I did not get this error if I remove extends ThreadProvider of autowired class, but I really need ThreadProvider abstract class.
If there is an interface anywhere in the ThreadProvider hierarchy try putting the name of the Interface as the type of your service provider, eg. if you have say this structure:
public class ThreadProvider implements CustomInterface{
...
}
Then in your controller try this:
#Controller
public class ChiusuraController {
#Autowired
private CustomInterface chiusuraProvider;
}
The reason why this is happening is, in your first case when you DID NOT have ChiusuraProvider extend ThreadProvider Spring probably was underlying creating a CGLIB based proxy for you(to handle the #Transaction).
When you DID extend from ThreadProvider assuming that ThreadProvider extends some interface, Spring in that case creates a Java Dynamic Proxy based Proxy, which would appear to be an implementation of that interface instead of being of ChisuraProvider type.
If you absolutely need to use ChisuraProvider you can try AspectJ as an alternative or force CGLIB based proxy in the case with ThreadProvider also this way:
<aop:aspectj-autoproxy proxy-target-class="true"/>
Here is some more reference on this from the Spring Reference site: http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/classic-aop-spring.html#classic-aop-pfb
You should put this line in your application context:
<context:component-scan base-package="com.cinebot.service" />
Read more about Automatically detecting classes and registering bean definitions in documentation.

Spring annation for service

I am trying to use Spring annotation to define controller, service and dao, but failed.
the error message is
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.abs.absbase.ABSService] is defined: Unsatisfied dependency of type [interface com.abs.absbase.ABSService]: expected at least 1 matching bean
but I do define the service.
Another question is, how to define a sessionfactory to overwrite the HibernateDaoSupport in the ABSDaoImpl ?
Thanks
Source code is
#Controller
#RequestMapping("/abs.do")
public class ABSController {
#Autowired
#Qualifier("ABSService")
ABSService service;
...
}
#Service(value="ABSService")
public class ABSServiceImpl implements ABSService {
#Autowired
#Qualifier("ABSDao")
ABSDao dao;
}
#Repository(value="ABSDao")
public class ABSDaoImpl extends HibernateDaoSupport implements ABSDao {
...
}
According to me you just need to remove the #Qualifier annotation you have defined above the declaration of ABSService object in the controller. And also remove the (value="ABSService") from the #Service annotation on the service.
Hope this helps you.
Cheers.

Resources