Rolf Streefkerk
Rolf Streefkerk

Reputation: 23

Spring Data Neo4j 4.0: Duplicate nodes created, should create relationship instead

Summary: With SDN4, I'm persisting 10 objects of which half have the same content only the id's to which they are linked differ. The linking ID's are set as @Transient. Still, two objects are created with the same content instead of one with two links to it. How can I avoid this behavior?

Detail: We have two domain objects defined and the information sources via CSV, they look as follows:

Domain object A CSV:

key,name
1,test1
3,test3

POJO A:

@Transient
private int key;    
private String name;

@Relationship(type = "HAS_CERTIFICATION", direction = "OUTGOING")
private Set<B> bObject = new HashSet<>();

public void setName(String name) {
    this.name = name;
}

@Relationship(type = "HAS_CERTIFICATION", direction = "OUTGOING")
public void hasCertification(B b) {
    bObject.add(b);
    b.getA().add(this);
}

Domain object B:

foreignKey,name,value
1,ISO9001,TRUE
1,ISO14001,TRUE
3,ISO9001,TRUE
3,ISO14001,TRUE

POJO B:

@Transient
private int foreignKey;
private String name;
private String value;

@Relationship(type = "HAS_CERTIFICATION", direction = "INCOMING")
private Set<A> a = new HashSet<>();

public void setName(String name) {
    this.name = name;
}

public void setValue(String value) {
    this.value = value;
}

@Relationship(type = "HAS_CERTIFICATION", direction = "INCOMING")
public Set<A> getA() {
    return a;
}

These CSV files are parsed and loaded into SDN4 within their respective POJO's (A and B).

Now we loop over these objects and add the relationships:

private void aHasCertification(
        Optional<List<B>> b,
        Optional<List<A>> a) {
    for (A aObj : a()) {
        for (B bObj : b()) {
            if(bObj.getForeignKey() == aObj.getKey()) {
                aObj.hasCertification(bObj);
            }
        }
    }
}

Then the root repository, repositoryA, is used to save the loaded objects. repositoryA.save(domainObjectA);

Now when I query the database; match n return n;

for each of the A objects there will be two ISO9001 and two ISO14001 objects. Instead of what I would expect, one of each with two links to A:1 and A:3.

Upvotes: 2

Views: 486

Answers (1)

Luanne
Luanne

Reputation: 19373

If I understand you correctly, instead of

enter image description here

you're expecting

enter image description here?

The OGM has no way of knowing that two instances of B with the same "name" are the same node. What you will need to do is load the B node by property and if it exists, use it to relate to A, otherwise create it. I suspect you'll need to process the CSV data a bit further instead of modelling your objects with almost a 1:1 mapping to a CSV row.

Upvotes: 2

Related Questions