Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@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?

like image 310
r.rodriguez Avatar asked Feb 15 '23 17:02

r.rodriguez


2 Answers

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.

like image 188
chrylis -cautiouslyoptimistic- Avatar answered Feb 17 '23 21:02

chrylis -cautiouslyoptimistic-


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.

like image 25
Steve Avatar answered Feb 17 '23 22:02

Steve