Skip to content

Relationship not persisted with String/UUID id and double mapping (incoming & outgoing) #2282

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
paolodedo opened this issue Jun 8, 2021 · 2 comments
Assignees
Labels
status: needs-investigation An issue that has been triaged but needs further investigation

Comments

@paolodedo
Copy link

paolodedo commented Jun 8, 2021

SDN 6.1.1

Hello,

I have noticed a strange behaviour creating relationships for my nodes.

My entities:

@Node
@Getter
@Setter
public class Group {

    @Id
    @GeneratedValue(generatorClass = GeneratedValue.UUIDGenerator.class)
    private UUID id;

    private String name;

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    @JsonIdentityReference(alwaysAsId = true)
    @Relationship(type = "IS_TAGGED_WITH", direction = Relationship.Direction.OUTGOING)
    private Set<Tag> tags = new LinkedHashSet<>();
@Node
@Getter
@Setter
public class Tag {

    @Id
    @GeneratedValue(generatorClass = GeneratedValue.UUIDGenerator.class)
    private UUID id;

    private String name;

    @JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
    @JsonIdentityReference(alwaysAsId = true)
    @Relationship(type = "IS_TAGGED_WITH", direction = Relationship.Direction.INCOMING)
    private Set<Group> groups = new LinkedHashSet<>();

the relationship saving:

@Override
    public Tag linkGroup(UUID id, UUID groupId) throws NoSuchElementException, IllegalArgumentException {

        Tag tag = tagRepository.findById(id).orElse(null);
        Group group = groupRepository.findById(groupId).orElse(null);

        if (tag == null)
            throw new NoSuchElementException("Tag " + id + " not existent");
        else if (group == null)
            throw new NoSuchElementException("Group " + groupId + " not existent");

        if (tag.getGroups().contains(group))
            throw new IllegalArgumentException(
                "Relationship already exists between Tag " + id + " and Group " + groupId);

        tag.getGroups().add(group);
        return tagRepository.save(tag);
    }

This scenario leads to a non-saving relationships on Neo4j.

There are 2 changes that will magically make the mechanism work...they are:

  1. Change the id of Group entity from UUID (or String) to Long
  2. Removing the field "tags" with Relationship.OUTGOING from Group entity, so basically leaving it only on Tag entity

That is so strange as I have another entity (with Long id) that is perfectly working with relationship to the Group entity...it has, as only difference, the Long id.

Thanks for your help

@meistermeier
Copy link
Collaborator

meistermeier commented Jun 8, 2021

To persist the relationship correctly, you would have to set the elements in the collection of each other.
So basically not only tag.getGroups().add(group) but also group.getTags().add(tag).
More details can be found here: #2264 (comment)

The reason why it is working with the Long is more or less random The path the persisting mechanism walks through the properties is given (randomly) by Spring Data commons. The changed type will change the order.
But just to be sure, I will check the id type change again.

Duplicate of #2264

@meistermeier meistermeier added status: needs-investigation An issue that has been triaged but needs further investigation and removed status: waiting-for-triage An issue we've not yet triaged labels Jun 8, 2021
@meistermeier
Copy link
Collaborator

I took some time to see if the id type makes any difference.
As a conclusion: No, it can be that the order gets changed of values that get processed but in the end it behaves about the same.

As stated above, you should really take care of setting a complete pair of relationships if you really have to do the bidirectional mapping.

If there is anything I have might missed in the context of this issue, feel free to re-open this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs-investigation An issue that has been triaged but needs further investigation
Projects
None yet
Development

No branches or pull requests

3 participants