Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
12-01-2021 02:30 AM
Hi,
this is our first Neo4J-Project, so sorry if I'm missing something obvious.
We use Spring Boot 2.6.0 with Spring Data Neo4J 6.2.0 and a remote Neo Aura DB (the free version 4.3.0). I also tested it with a local server (4.3.5 and 4.3.3), this doesn't work either.
I have 2 classes (User, MindMapNode) to which I want to add a Relationship from User to MindMapNode. When using curl, it adds a new Node, but it doesn't add the Relationship. There is no Exception or HTTP-Status Code other than 200 or something logged in the console, nothing.
// imports...
@Node
@Data
@ToString
@Builder
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
public class User {
@Id @GeneratedValue private Long id;
@Property
@Getter @Setter @NonNull
private String username;
@Getter @Setter
@Relationship(type = "OWNS", direction = Relationship.Direction.OUTGOING)
private List<MindMapNode> graphs;
public void saveGraphForUser(MindMapNode root) {
if (graphs == null) graphs = new ArrayList<>();
graphs.add(root);
}
public User withId(Long id){
if (this.getId() == null) {
return new User(id, this.username, this.password, this.graphs);
}
else if (this.getId().equals(id)) {
return this;
} else {
return new User(id, this.username, this.password, this.graphs);
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return id.equals(user.id) && username.equals(user.username);
}
@Override
public int hashCode() {
return Objects.hash(id, username);
}
}
//imports...
@Node
@AllArgsConstructor
public class MindMapNode {
@Getter
@Id @GeneratedValue
private final Long id;
@Getter @Setter @NonNull
private String title;
// other properties...
public MindMapNode withId(Long id){
if (this.getId() == null) {
return new MindMapNode(id, this.getTitle(), this.getDescription(), this.getWeight(), this.getNeighbors());
}
else if (this.getId().equals(id)) {
return this;
} else {
return new MindMapNode(id, this.getTitle(), this.getDescription(), this.getWeight(), this.getNeighbors());
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MindMapNode that = (MindMapNode) o;
return id.equals(that.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
@Service
public class MindMapNodeService {
@Autowired
private MindMapNodeRepository mindMapNodeRepository;
@Autowired
private UserService userService;
public MindMapNode saveMindMap(Long userid, String name) {
Optional<User> optuser = userService.getUserById(userid);
if (optuser.isEmpty()) throw new IllegalArgumentException("Userid is not known");
MindMapNode res = saveMindMapNode(new MindMapRoot("New Title", "", 50, new HashSet<>(), name));
optuser.get().saveGraphForUser(res);
return res;
}
}
//imports...
@RestController
@RequestMapping("/mindmap")
@RequiredArgsConstructor
public class MindMapController {
@Autowired
private MindMapNodeService mindMapNodeService;
@PostMapping("/add")
public MindMapNode addMindMap(@RequestParam Long userid, @RequestParam String name) {
return mindMapNodeService.saveMindMap(userid, name);
}
}
And finally the curl-command:
curl -X POST -F "userid=<id here>" -F "name=newMindMap" http://localhost:8080/mindmap/add
What am I missing?
Solved! Go to Solution.
12-02-2021 06:09 AM
Just a wild guess...you are not saving the User
.
I can see in the MindMapNodeService
:
saveMindMapNode
does only this) a new MindMapRoot
/MindMapNode
MindMapNode
to the User
But after 3. you have to save the User
to persist the change to the collection.
For completeness, you can skip the save of the MindMapNode
, just add it to the User
and persist it. On save SDN will cascade into all relationships and create the related nodes if needed.
Also you should add a @Transactional
around the saveMindMap
method to create one logical Spring transaction. If you would keep the code as it is, you might run into a race condition between the transactions of the save of the MindMapNode
and the User
.
12-02-2021 06:09 AM
Just a wild guess...you are not saving the User
.
I can see in the MindMapNodeService
:
saveMindMapNode
does only this) a new MindMapRoot
/MindMapNode
MindMapNode
to the User
But after 3. you have to save the User
to persist the change to the collection.
For completeness, you can skip the save of the MindMapNode
, just add it to the User
and persist it. On save SDN will cascade into all relationships and create the related nodes if needed.
Also you should add a @Transactional
around the saveMindMap
method to create one logical Spring transaction. If you would keep the code as it is, you might run into a race condition between the transactions of the save of the MindMapNode
and the User
.
12-02-2021 07:59 AM
Hi there,
it took a while, but your tip was the right clue 🙂
Adding a userService.saveUser(user) did the trick. We will look at your tip for completeness next and try this out. I also added the @Transactional, but will need to dive a little further into what it actually means.
Thank you!
All the sessions of the conference are now available online