Spring io @Autowired: The blank final field may not have been initialized

29,787

Solution 1

Having @Autowired and final on a field are contradictory.

The latter says: this variable has one and only one value, and it's initialized at construction time.

The former says: Spring will construct the object, leaving this field as null (its default value). Then Spring will use reflection to initialize this field with a bean of type WorkspaceRepository.

If you want final fields autowired, use constructor injection, just like you would do if you did the injection by yourself:

@Autowired
public WorkspaceController(WorkspaceRepository repository) {
    this.repository = repository;
}

Solution 2

Exactly, you have to provide a constructor that assigns the final field

private final WorkspaceRepository repository;

@Autowired
public WorkspaceController(WorkspaceRepository repository){
  this.repository = repository;
}

And Spring will be able to figure out how to initialise the object and inject the repository via the constructor

Share:
29,787
Pinwheeler
Author by

Pinwheeler

Updated on January 04, 2020

Comments

  • Pinwheeler
    Pinwheeler over 4 years

    what I assume is a pretty basic question here-

    There are several flavors of questions regarding this error, but none in the first 5 results that have the added nuance of Spring.

    I have the beginnings of a REST-ful webapp written in spring. I am trying to connect it to a database.

    I have an entity named Workspace and am trying to use the spring injection of a bean( correct terminology ?) to save an instance of the workspace entity

    package com.parrit;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.util.Assert;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.parrit.models.Workspace;
    import com.parrit.models.WorkspaceRepository;
    
    @RestController
    @RequestMapping("/workspace")
    public class WorkspaceController {
    
        @Autowired
        private final WorkspaceRepository repository;
    
        @RequestMapping(method = RequestMethod.POST)
        void save( @RequestBody String workspaceHTML) {
            Workspace ws = new Workspace();
            ws.setHTML(workspaceHTML);
            repository.save(ws);
        }
    }
    

    My error is on the repository variable private final WorkspaceRepository repository. The compiler is complaining that it may not be initialized and attempting to run the app yields the same result.

    How do I get an instance of this repository object into my controller in order to do save operations on it?