Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 885
Pinwheeler Avatar asked Jan 03 '16 18:01

Pinwheeler


People also ask

Can Autowired fields be final?

Classes Using Field Injection Are Non-Final, but Are Prone to Circular Dependencies. If you try and declare an @Autowired field as final , you'll get a compile error.

Why Autowired is not working?

When @Autowired doesn't work. There are several reasons @Autowired might not work. When a new instance is created not by Spring but by for example manually calling a constructor, the instance of the class will not be registered in the Spring context and thus not available for dependency injection.

Can we use @autowired in spring?

In Spring, you can use @Autowired annotation to auto-wire bean on the setter method, constructor , or a field . Moreover, it can autowire the property in a particular bean. We must first enable the annotation using below configuration in the configuration file. We have enabled annotation injection.

What will happen if I make @autowired as false?

By default, the @Autowired annotation implies that the dependency is required. This means an exception will be thrown when a dependency is not resolved. You can override that default behavior using the (required=false) option with @Autowired .


2 Answers

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; } 
like image 98
JB Nizet Avatar answered Sep 19 '22 16:09

JB Nizet


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

like image 38
Sleiman Jneidi Avatar answered Sep 21 '22 16:09

Sleiman Jneidi