-2

I am trying to create an application following example code in the book "Spring Data" by Petri Kainulainen. I have a service RepositoryContactService package com.packtpub.springdata.jpa.service;

@Service("service")
public class RepositoryContactService implements ContactService {

My ApplicationContext class sets the package of the service for scanning

@Configuration
@ComponentScan(basePackages = { "com.packtpub.springdata.jpa.service" })
@EnableTransactionManagement
@EnableWebMvc
@EnableJpaRepositories("com.packtpub.springdata.jpa.repository")
@PropertySource("classpath:application.properties")
public class ApplicationContext extends WebMvcConfigurerAdapter {

I am running class Test with declaration

@Autowired
private static RepositoryContactService service;

and code in the main method

Contact contact = new Contact("handro1104@gmail.com", "handro");
service.save(contact);

The problem is that the line "service.save(contact);" is giving me service null.

Ahmad Al-Kurdi
  • 2,248
  • 3
  • 23
  • 39
handro1104
  • 39
  • 1
  • 4
  • Please show the declaration of the test class and all annotations. – dunni Sep 01 '18 at 20:57
  • 1
    Spring will not @Autowire static variables - so your overall setup is invalid. You need to create a class that will hold the RepositoryContactService, and that main will invoke via Spring's application context, for Spring to be able to help you set things up. – moilejter Sep 02 '18 at 01:10

3 Answers3

1

From a class that is annotated @Service only one bean is created because default manner of @Service is Singleton so you does not need auto-wire these class bean statically.

Change:

@Autowired
private static RepositoryContactService service;

To :

@Autowired
private RepositoryContactService service;
Mehdi Tahmasebi
  • 1,074
  • 6
  • 10
0

Thanks to all who have responded. I found out that you cannot autowire a static field and tried

@Component
public class Test {
    @Autowired
    private ContactService service;

    public static void main(String[] args) {
        Test test = new Test();
        Contact contact = new Contact("handro1104@gmail.com", "handro");
        ContactService service = test.service;
        service.save(contact);
    }

But that didn't work either. I also tried

public class Test {
    public static void main(String[] args) {
        ContactService service = new RepositoryContactService();
        Contact contact = new Contact("handro1104@gmail.com", "handro");
        service.save(contact);
    }

With

    @Resource // Also tried with @Autowired
    private ContactRepository repository;
@Configurable
public class RepositoryContactService implements ContactService {
    @Override
    public void save(Contact updated) {
        repository.save(updated);
    }

But repository was null here.

For more clarity, I have

@Configuration
@ComponentScan(basePackages = { "com.packtpub.springdata.jpa.service" })
@EnableTransactionManagement
@EnableWebMvc
@EnableJpaRepositories("com.packtpub.springdata.jpa.repository")
@PropertySource("classpath:application.properties")
public class ApplicationContext extends WebMvcConfigurerAdapter {

So that RepositoryContactService is scanned and ContactRepository in com.packtpub.springdata.jpa.repository can be autowired. At some point I even added com.packtpub.springdata.jpa.repository to @ComponentScan.

handro1104
  • 39
  • 1
  • 4
-1

There can be many reasons for which Spring is unable to autowire RepositoryContactService.

  1. RepositoryContactService is not in the packages which are declared in @ComponentScan. For this, try adding the packages in which RepositoryContactService and ContactService is present to the list in @ComponentScan.
  2. You have written that you have written class Test. If it is a Unit testing class, then check all annotations used for Unit Testing are present.

Though this will not solve null problem but I prefer programming to an Interface and using Qualifier to tell spring container which implementation of Interface to Inject.

Rishabh Agarwal
  • 1,988
  • 1
  • 16
  • 33