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?
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.
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.
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.
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 .
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; }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With