1
votes

Good Evening,

I am using SDN 3, and am running into problems with removing simple relationships (RelateTo) in my underlying graph. The scenario is that I want to establish a Friend request/approval system amongst Users in my web application. I have no problem issuing the request by creating a "HAS_REQUESTED" relationship between Users. but once the User receiving the friend request hits "approve", the "FRIENDS_WITH" relationship is established without properly removing the "HAS_REQUESTED" relationship. the code below walks through the process:

The relevant Controller method

@RequestMapping(value="/approve/friend/{friendId}")
public String approveFriend(@PathVariable("friendId") String friendId){
    User me = userService.findByEmail(userService.getAuthenticatedUser().getName());
    userService.removeOldRequests(friendId, me);
    userService.approveFriendship(friendId, me);
    return "redirect:/friends";
}

The UserService method in question. 'me' is the authenticated user who originally sent the friend request to 'friendId/friend':

public void removeOldRequests(String friendId, User me){
try{
    User friend = userRepository.findByUserId(friendId);
    friend.addStartNodeForUsersRequestingMe(me, false);
    template.save(friend);
}catch(Exception e){
    e.printStackTrace();
}

and here is my User entity Node (excluding unrelated fields/getters/setters.)

@NodeEntity

public class User {

@GraphId Long nodeId;
@Indexed
String userId;
String username;
String firstName;
String lastName;
String email;
String aboutMe;
String Quote;
String favoriteBook;
int age;
Date userCreation;
String sex;
String password;
Role role;
byte[] picture;


@RelatedTo(type="FRIENDS_WITH", direction=Direction.BOTH)
@Fetch
Set<User> friends;


@RelatedTo(type="HAS_FRIEND_REQUEST")
@Fetch
Set<User> startNodeForUsersRequestingMe;

@RelatedTo(type="HAS_FRIEND_REQUEST", direction=Direction.INCOMING)
@Fetch
Set<User> UsersWhoHaveRequestedMe;


public void addStartNodeForUsersRequestingMe(User user, boolean flag){
    if(flag){
        this.startNodeForUsersRequestingMe.add(user);
    }else{
        this.startNodeForUsersRequestingMe.remove(user);
    }

}
public void addUsersWhoHaveRequestedMe(User user, boolean flag){
    if(flag){
        this.UsersWhoHaveRequestedMe.add(user);
    }else{
        this.UsersWhoHaveRequestedMe.remove(user);
    }

}

The repository method I am using to return the current user's friend requests is below. Right now it is configured to just return any relationship the user has that is "HAS_FRIEND_REQUEST" just for testing purposes to see if I can get User A with one friend request from User B to NOT be returned.

@Query("START user=node({0})"
    +"MATCH (user)-[:HAS_FRIEND_REQUEST]-(friend)"
    + "return friend;")

Iterable getUserFriendRequests(User user);

Any guidance on how to properly remove the "HAS_FRIEND_REQUEST" in a clean manner would be greatly appreciated. either that, or maybe a better way to handle the "friend request Handshake" idea. If you have any questions or concerns for me, please do not hesitate to bring them to my attention.

1

1 Answers

1
votes

You can remove the target user from the collection or use the Neo4jTemplate method to delete the relationship.

template.deleteRelationshipBetween(Object start, Object end, String type)