0

I am creating an application which uses Controller, Service and Dao classes.Service and Dao are created as interface which are implemented using their implementation classes. I have a controller class named UserGroupController and its service as UserGroupService. .The code snippet would be:

@Controller
@RequestMapping("module/usergroup")
public class UserGroupController 
{
    @Autowired
    UserGroupService userGroupService;

This @AutoWired annotation is causing the issue and when I remove just that annotation, everything works without exception.But if I do not use that annotation, whenever I try to access any method my service class, I am getting a null pointer exception.

My Service class is like shown below:

@Repository("userGroupService")
public interface UserGroupService

and its implementation is:

public class UserGroupServiceImpl implements UserGroupService
{
    @Autowired
    @Qualifier(value = "userGroupDao")
    UserGroupDao userGroupDao;

And the exception is:

SEVERE: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userGroupController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.smartwcm.core.user.service.UserGroupService com.smartwcm.admin.user.controller.UserGroupController.userGroupService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.smartwcm.core.user.service.UserGroupService] 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:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:383)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:283)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4206)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4705)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:840)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1057)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:463)
    at org.apache.catalina.core.StandardService.start(StandardService.java:525)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:754)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.smartwcm.core.user.service.UserGroupService com.smartwcm.admin.user.controller.UserGroupController.userGroupService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.smartwcm.core.user.service.UserGroupService] 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$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:514)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 28 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.smartwcm.core.user.service.UserGroupService] 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.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:949)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:818)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:730)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:486)
    ... 30 more
JamesENL
  • 6,400
  • 6
  • 39
  • 64
Geo Thomas
  • 1,139
  • 3
  • 26
  • 59
  • ok.... so what is the BeanCreationException you are getting? Without that, we can't really help. And if you remove @Autowired, then your userGroupService will be null, because nothing will be injected into it – JamesENL Jan 29 '15 at 05:20
  • The exception message is extremely clear: There's no bean available that matches what you're requesting for injection. Figure out why that bean isn't included. – chrylis -cautiouslyoptimistic- Jan 29 '15 at 05:23
  • You shoud anotate your UserGroupServiceImpl – Milkmaid Jan 29 '15 at 05:23
  • You also shouldn't need to qualify any of your `@Service` or `@Repository` annotations with anything after them. As long as they are being picked up by classpath scanning, they are eligible to be autowired by type – JamesENL Jan 29 '15 at 07:56

5 Answers5

1

You should be following the standard Repository, Service, Controller pattern.

@Controller : Controller annotation is used to denote that the class is controller. It contains method which serve the http requests, request mappings are done at method level or class level.
@Service : Annotate all your service classes with @Service. All your business logic will be in Service classes. Controller and DAO layers will not have any business logic in there.
@Repository : Annotate all your DAO classes with @Repository. All your database access logic should be in DAO classes.

So in your case, annotations should be:

@Repository("userGroupDao")
public class UserGroupDaoImpl implements UserGroupDao

@Service("userGroupService")
public class UserGroupServiceImpl implements UserGroupService

@Controller
public class UserGroupController
Vimal Mathew
  • 575
  • 3
  • 10
  • Thank you, this was exactly the solution I was looking for....The solution worked for my application and was educative too – Geo Thomas Jan 29 '15 at 14:52
0

Why annotate it with @Repository? you can use that for your DAO classes.

(1) Annotate with @Service instead

@Service
public interface UserGroupService

(2) Or you can define your UserGroupService as a bean in your Spring configuration:

<bean id="userGroupService" class="com.your.package.UsergroupService" />
jmcg
  • 1,547
  • 17
  • 22
0

It will work if you move the @Repository annotation to the implementation class. Please find below the sample code:

Interface class:

public interface Test {
    public void printMessage(String msg);
}

Implementation class:

@Repository("testService")
public class TestImpl implements Test {

    @Override
    public void printMessage(String msg) {
    System.out.println(msg);
    }

}

Configuration class:

@Configuration
@ComponentScan("com.praxissummit.eperf.api.domain.test")
public class TestConfig {

}

Main class:

public class Main {

    public static void main(String[] args) {
        ApplicationContext ctx = 
           new AnnotationConfigApplicationContext(TestConfig.class);
        ctx.getBean("testService", Test.class).printMessage("Hello world!!");
    }
}

If I move the @Repository annotation to the interface, spring throws No bean named 'testService' is defined

Note: You should actually annotate your service class with @Service, not @Repository

Mithun
  • 7,747
  • 6
  • 52
  • 68
0

@Autowired is confusing sometimes. You can use more general java @Resource (jsr250) annotation. @Resource means get me a known resource by name. The name is extracted from the name of the annotated setter or field, or it is taken from the name-Parameter. @Resource has a built-in fallback, which kicks in when resolution by-name fails. In this case, it falls back to the @Autowired-kind resolution by-type.

@Controller
@RequestMapping("module/usergroup")
public class UserGroupController 
{
    @Resource(name="UserGroupService")
    UserGroupService userGroupService;

and for your service you can choose from @Component or @Service

@Service
public interface UserGroupService { }

Hope it will sort out your problem. Check out the difference between @Autowired and @Resource for more clarity. @Resource vs @Autowired

@Service or @Component annotation is used for spring container, it will create the object on the fly. You can even opt out the above annotation if you are using @Resource(provided you use @Resource every where for your service class)

Community
  • 1
  • 1
Sudip7
  • 2,384
  • 3
  • 27
  • 35
-1

You need to add the @Service annotation to your service class implementation, so that it can be picked up by classpath scanning, added to the Spring context and then be eligible to be Autowired.

package com.foo.bar.service;

@Service
public class UserGroupServiceImpl implements UserGroupService
{
    @Autowired
    @Qualifier(value = "userGroupDao")
    UserGroupDao userGroupDao;

Also ensure that if your service class is in package com.foo.bar.service, that you have that package included in the component scan package tag in your XML. Example:

<context:component-scan base-package="com.foo.bar" />
JamesENL
  • 6,400
  • 6
  • 39
  • 64