Reputation: 13519
Using Spring Boot and Neo4J, I've created two @NodeEntity
's. They are User
and Right
. In my model, when you create a relationship between a User and Right, I call it a Privilege
I cannot save the @RelationshipEntity
, Privilege
(from within either of the @NodeEntity
's or the RelationshipEntity
).
Example Code
User.java (backed by interface UserRepository extends GraphRepository)
@NodeEntity
public class User {
@Autowired Neo4jTemplate template;
@GraphId Long id;
String fullName;
@Indexed(unique=true) String email;
@Fetch @RelatedTo(type="HAS_RIGHT")
Set<Right> rights;
public void addRight(Right r) {
Privilege p = new Privilege (this, r)
template.save(p) // This always throws a NullPointerException
}
/*** Getters and Setters ***/
}
Right.java (backed by interface RightRepository extends GraphRepository)
@NodeEntity
public class Right {
@GraphId Long id;
String name;
/*** Getters and Setters ***/
}
Privilege.java (Not backed by a repository interface) - PROBLEM CLASS
@RelationshipEntity(type="HAS_RIGHT")
public class Privilege {
@Autowired
Neo4jTemplate template; // This is always null
@GraphId Long id;
@StartNode User user;
@EndNode Right right;
public Privilege() {}
public Privilege(User user, Right right) {
this.user = user;
this.right = right;
}
public void save() {
template.save(this); // Always throws a NullPointerException
}
}
In my test case I can call (this works):
User user = userRepository.findByEmail("[email protected]");
Right adminRight = rightRepository.findByName("ADMINISTRATOR");
Privilege adminPrivilege = new Privilege(user, adminRight);
template.save(adminPrivilege);
But I'd prefer to call (this does not work):
User user = userRepository.findByEmail("[email protected]");
User.addRight (rightRepository.findByName("ADMINISTRATOR"));
But I also can't access template from within either of the NodeEntities.
Upvotes: 2
Views: 3784
Reputation: 13519
My mistake was that I was instantiating the class manually, therefore it was not spring managed. Adding the @Component annotation to the class and asking Spring to give me the class resolved the problem.
@Component // This is the line that saved the day!
@RelationshipEntity(type="HAS_RIGHT")
public class Privilege {
@Autowired
Neo4jOperations operations;
@GraphId Long id;
@StartNode User user;
@EndNode Right right;
public Privilege() {
;;
}
public void createRelationship(User user, Right right) {
this.user = user;
this.right = right;
this.save();
}
/*** Getters and Setters ***/
}
Then to instantiate it:
...
@Autowired ApplicationContext applicationContext;
...
Privilege privilege = applicationContext.getBean(Privilege.class);
privilege.createRelationship(user, ADMINISTRATOR);
Upvotes: 1
Reputation: 4461
You can create relationship by using Neo4jTemplate Or Neo4jOperations.
Change it to constructor injection.
@Autowired
public Constructor(Neo4jOperations operations) {
this.neo4jOperations = operations;
}
Once you have both the nodes by calling the repository, do something like:
Relation relation = neo4jOperations.createRelationshipBetween(user, right, Relationship.class, "RELATION_NAME", true);
neo4jOperations.save(relation);
Upvotes: 1