Ivawen
Ivawen

Reputation: 13

@Autowired does not inject Mongodb repository or service -nullPointerException-

i am using mongodb repository wired in a service and i want to wire that into another component so i can use the findAll.

@Service
@Transactional
public class SettingService implements SettingInterface {

  public SettingService() {
  }

  private SettingRepository settingRepository;

  @Autowired
  public SettingService(SettingRepository settingRepository) {
    this.settingRepository = settingRepository;
  }

  @Override
  public List<Setting> findAll() {
    return settingRepository.findAll();
  }
}

Repository

public interface SettingRepository extends MongoRepository<Setting, String> {
}

Class i want to inject my data in

@Component
public class Config {

    private  SettingService service;

    public Config() {
    }

    @Autowired
    public Config(SettingService service) {
        this.service = service;
    }

// The doSomething method is being called from a constructor 

  public Order(List<Item> listOfItems) {
    // Initialize ArrayLists
    order = new ArrayList<>();
    results = new ArrayList<>();
    possibleResults = new ArrayList<>();
    Accepted = new HashMap<>();


    doSomething();

    // Soft copy order
    order.addAll(listOfItems);
  }


    @Transactional
    public void doSomething() {
        List<Setting> settingList = service.findAll();
        // Manipulate Data


  }
}

the problem I am having is that the service injection returns null, I ran the app in debug mode and put a breakpoint where i call the findAll, it throws nullPointerException, the Service was not injected.

I also tried to autowire the repository straight into my config class instead of the service but same results nullPointerException

PS: The same configuration with the same service injection seems to work just fine in one of my controllers, service wired up successfully, but it does not work with my @Component. Also tried to use @Service, @Transactiona but same results.

EDIT: Also tried to autowire repository like this:

    @Repository
    public interface SettingRepository extends MongoRepository<Setting, String> {
    }

My Component class

// tried it with @Component as well 
@Service
@Transactional
public class Config {

    private SettingRepository SettingRepository;

    @Autowired
    public Config(SettingRepository SettingRepository) {
        this.SettingRepository = SettingRepository;
    }

    public Config() {
    }


    public Config(List<Item> listOfItems) {
        // Initialize ArrayLists
        order = new ArrayList<>();
        possibleConfigurations = new ArrayList<>();
        acceptedConfigurations = new ArrayList<>();
        mapOfAcceptedConfigurations = new HashMap<>();

        doSomething();

        // Soft copy order
        order.addAll(listOfItems);
    }

   public void doSomething() {
        List<Setting> settingList = SettingRepository.findAll();

        Level securityLevel = settingList.get(0).getSecurityLevel();
        Level fragileAndHeavyLevel =settingList.get(0).getLevelFragileItem();

    }

this has produced the same thing, i am wondering if having multiple constructors could cause the autowiring to be null. I am autowiring only the one constructor that injects the repo

Upvotes: 0

Views: 1072

Answers (2)

Ivawen
Ivawen

Reputation: 13

UPDATE SOLUTION:

I found where the problem comes from, i am calling doSomething from this constructor

public Config(List<Item> listOfItems) {
    // Initialize ArrayLists
    order = new ArrayList<>();
    possibleConfigurations = new ArrayList<>();
    acceptedConfigurations = new ArrayList<>();
    mapOfAcceptedConfigurations = new HashMap<>();

    doSomething();

    // Soft copy order
    order.addAll(listOfItems);
}

doSomething method fetches the data from the repository but the constructor does not inject it rather I was using another constructor to autoWire which in this case will return nullPointerException, so my fix was to move the call of doSomething to the constructor where I autowired it at

@Autowired
public Config(SettingRepository settingRepository) {
    this.settingRepository = settingRepository;

    doSomething();

}

Upvotes: 0

Eklavya
Eklavya

Reputation: 18480

We can use @Component across the application to mark the beans as Spring's managed components. Spring only pick up and registers beans with @Component and doesn't look for @Service and @Repository in general.

So you can't autowire @Service and @Repository in component if component scan order is not specified.

Use @Configuration instead of @Component if you want to autowire and use @Repository on repository class.

Upvotes: 1

Related Questions