0

Here's my nodes :

@NodeEntity
public class User {

    @Id
    @Index(unique = true)
    @GeneratedValue(strategy = UuidStrategy.class)
    private String id;

    @Relationship(type = "LIKE")
    private Collection<Pattern> likedPatterns;
    ...
}


@NodeEntity
public class Pattern {
    @Id
    @Index(unique = true)
    @GeneratedValue(strategy = UuidStrategy.class)
    private String id;
    
    private String name;

    @Relationship(type = "LIKE", direction = Relationship.INCOMING)
    private List<User> likes;
    ...
}

I try to delete relationship between user and pattern :

@Override
@Transactional(readOnly = false)
public void deleteLikedPattern(String patternId, Long authId) {
    User user = userRepository.findByAuthId(authId);
    user.getLikedPatterns().removeIf(p -> p.getId().equals(patternId));
    userRepository.save(user);
    
}

In the begining user has 2 pattern. On debug I can see that patternId is found in pattern collection, and corresponding pattern is removed from the list. Then the save() is done, and I got no error. But if I check in DB, pattern and user are still linked, relationship is still here.

I tried solution on this post Neo4j OGM how to delete relationship which works. Which means that if I want to delete a relationship, I have to delete association in both entities list :

  • delete pattern from user pattern's collection

  • delete user from pattern user's collection)

    which is a little tedious...

And in many other thread asking for same problem, people seems not to suggest to delete association on both sides. My question is : do I HAVE to delete association on both sides, or should it work by just removing pattern from user's favorites list?

Thx

Community
  • 1
  • 1
Lempkin
  • 1,458
  • 2
  • 26
  • 49

1 Answers1

0

First of all there is no need to fully explain your relationship mappings in both classes of not needed. (Personal note: From an architectural point of view bidirectional dependencies between classes are something I would try to avoid.)

The answer is that you only need to remove it at the "leading" end. This is your User. In the moment you persist the user the relationship will get removed because Neo4j-OGM a) sees the modification and b) cannot reach the cut off node to traverse back to the user and re-create it in the same process.

Some additional notes: There should not even exist a repository for Pattern if the example above sees the User as an aggregate root. So persisting a Pattern always requires to persist a related User. As I can see this is a little bit more complicated in your current domain model because you are using m:n (many to many) mapping. The idea of Spring Data is to give you the ability to think and work in DDD (domain driver design). I suggest to read this article http://udidahan.com/2009/01/24/ddd-many-to-many-object-relational-mapping/ and/or other ones on many to many with DDD.

meistermeier
  • 7,942
  • 2
  • 36
  • 45
  • Hi, thx for your answer but I'm not sure that I understand what you mean : "The answer is that you only need to remove it at the "leading" end. This is your User. In the moment you persist the user the relationship will get removed " -> I think this is exactly what I do but this is not working, that's my problem :) – Lempkin Jan 15 '19 at 10:52
  • About Pattern persisting, I didn't show the whole entities, just the parts that seems relevant for my problem, but a pattern is much more than that (as well for the User) – Lempkin Jan 15 '19 at 10:54
  • Is that possible that the `Pattern` can get found through other relationships (ignoring the directions) from the `User`? Generally speaking Neo4j-OGM travers all "reachable" nodes in the graph from the object/node you want to save/update. – meistermeier Jan 15 '19 at 11:04
  • actually there's many relationships between a user and a Pattern : user can own the pattern, can like it, can add it in his favorites. I'm new to neo4J but I thought that what I've shown above is the classic way to define a relationship, specifing both ends of the relationship in corresponding entities, one which is "Incoming" and the other "Outcoming". Specificity here is that, as you said, this is a "ManyToMany" as a user can like many pattern, and a pattern can be liked by many users, and I must be able to display those informations on different part of my app – Lempkin Jan 15 '19 at 13:13
  • In this case I suggest using a (very) finite depth for the saving like `0`. That will result in a `repo.save(user, 0)`. I am yet not sure if this even touches the relationships or ignores it. But give it a try before I find time. – meistermeier Jan 15 '19 at 13:36