Reputation: 1
I am making a small API using Spring Boot and Neo4J, but for some reason the @Autowired
attributes to the domains are null
in one of my @Service
class.
The automatically generated route correctly returns the nodes from Neo4J database, so I assume there must be some error in the beans connection.
The controller:
@RestController
public class NodeController {
@PostMapping("/metrics")
public MetricJSON computeMetrics(
@Valid @RequestBody MetricsPayload payload,
@Autowired SocialNetwork socialNetwork
) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return new MetricJSON(socialNetwork.fromRequest(payload));
}
The @Service
class:
@Service
public class SocialNetwork {
@Autowired
public NetworkRepository networkRepository;
@Autowired
public NodeRepository nodeRepository;
@Autowired
public Evolution evolution;
public PersonalNetwork fromRequest(@NotNull MetricsPayload payload) throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
Network network = this.networkRepository.findById(payload.getNetworkId()).orElseThrow(NotFoundException::new);
Node ego = this.nodeRepository.findByTag(payload.getEgoTag()).orElseThrow(NotFoundException::new);
SimpleWeightedGraph<Integer, DefaultWeightedEdge> opn = this.nodeRepository.extractOPN(ego, payload.getDepth());
return this.fromGraph(opn, ego, payload);
}
The Node
domain class:
@org.springframework.data.neo4j.core.schema.Node("Node")
public class Node {
@Id
private String id;
@Property("tag")
private String tag;
@Relationship(type = "FROM", direction = OUTGOING)
private Set<Node> outgoingNodes;
@Relationship(type = "TO", direction = INCOMING)
private Set<Node> incomingNodes;
public String getTag() {
return tag;
}
public Set<Node> getOutgoingNodes() {
return outgoingNodes;
}
The NodeRepository
class :
public interface NodeRepository extends Neo4jRepository<Node, String> {
Optional<Node> findByTag(String tag);
}
And yet, when I run the API I obtain this error:
Failed to complete request: java.lang.NullPointerException: Cannot invoke "com.api.repositories.NodeRepository.findByTag(String)" because "this.nodeRepository" is null
Upvotes: 0
Views: 65
Reputation: 1
You shouldn't use @Autowired
on a method parameter. It's not used by autowiring.
Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities.
Instead create a property of controller and use it in the method
@RestController
public class NodeController {
@Autowired SocialNetwork socialNetwork;
@PostMapping("/metrics")
public MetricJSON computeMetrics(
@Valid @RequestBody MetricsPayload payload
) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return new MetricJSON(socialNetwork.fromRequest(payload));
}
}
Upvotes: 0
Reputation: 44745
Using the @Autowired
annotation in controller methods isn't supported. You need to autowire them into the class itself. For example:
@RestController
public class NodeController {
@Autowired
private SocialNetwork socialNetwork; // Add this
@PostMapping("/metrics")
// Remove the SocialNetwork parameter from computeMetrics()
public MetricJSON computeMetrics(
@Valid @RequestBody MetricsPayload payload
) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
return new MetricJSON(socialNetwork.fromRequest(payload));
}
}
(Preferably, you use construction injection in stead of field injection with @Autowired
.)
The reason why you get this NullPointerException
is because Spring will treat the socialNetwork
parameter in your controller as a class where request attributes can be binded upon. This causes Spring to create a new instance of SocialNetwork
, but not as a bean. So in this new instance of SocialNetwork
, dependency injection won't happen.
Related: Why is my Spring @Autowired field null?
Upvotes: 1