r.rodriguez
r.rodriguez

Reputation: 669

@Autowire failing with @Repository

I am not being able to make @Autowire annotation work with a @Repository annotated class.

I have an interface:

public interface AccountRepository {
    public Account findByUsername(String username);
    public Account findById(long id);
    public Account save(Account account);
}

And the class implementing the interface annotated with @Repository:

@Repository
public class AccountRepositoryImpl implements AccountRepository {
    public Account findByUsername(String username){
        //Implementing code
    }
    public Account findById(long id){
        //Implementing code            
    }
    public Account save(Account account){
        //Implementing code
    }
}

In another class, I need to use this repository to find an account by the username, so I am using autowiring, but I am checking if it works and the accountRepository instance is always null:

@Component
public class FooClass {
    @Autowired
    private AccountRepository accountRepository;

    ...

    public barMethod(){
        logger.debug(accountRepository == null ? "accountRepository is NULL" : "accountRepository IS NOT NULL");
    }
}

I have also set the packages to scan for the components (sessionFactory.setPackagesToScan(new String [] {"com.foo.bar"});), and it does autowire other classes annotated with @Component for instance, but in this one annotated with @Repository, it is always null.

Am I missing something?

Upvotes: 4

Views: 19049

Answers (3)

Your problem is most likely that you're instantiating the bean yourself with new, so that Spring isn't aware of it. Inject the bean instead, or make the bean @Configurable and use AspectJ.

Upvotes: 6

Steve
Steve

Reputation: 9480

It seems likely that you haven't configured your Spring annotations to be enabled. I would recommend taking a look at your component scanning annotations. For instance in a Java config application:

@ComponentScan(basePackages = { "com.foo" })

... or XML config:

<context:annotation-config />
<context:component-scan base-package="com.foo" />

If your FooClass is not under the base-packages defined in that configuration, then the @Autowired will be ignored.

As an additional point, I would recommend trying @Autowired(required = true) - that should cause your application to fail on start-up rather than waiting until you use the service to throw a NullPointerException. However, if annotations are not configured, then there will be no failure.

You should test that your autowiring is being done correctly, using a JUnit test.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(
    classes = MyConfig.class, 
    loader = AnnotationConfigContextLoader.class)
public class AccountRepositoryTest {

    @Autowired
    private AccountRepository accountRepository;

    @Test
    public void shouldWireRepository() {
        assertNotNull(accountRepository);
    }

}

This should indicate whether your basic configuration is correct. The next step, assuming that this is being deployed as a web application, would be to check that you have put the correct bits and pieces in your web.xml and foo-servlet.xml configurations to trigger Spring initialisation.

Upvotes: 2

FabienM
FabienM

Reputation: 96

FooClass needs to be instancied by Spring to have his depencies managed. Make sure FooClass is instancied as a bean (@Component or @Service annotation, or XML declaration).

Edit : sessionFactory.setPackagesToScan is looking for JPA/Hibernate annotations whereas @Repository is a Spring Context annotation. AccountRepositoryImpl should be in the Spring component-scan scope

Regards,

Upvotes: 0

Related Questions