Skip to content

Persistence logic bails out on the wrong combination of source and relationship. #2289

Closed
@BenBohannon

Description

@BenBohannon

I'm having difficulty with SDN frequently not persisting relationships between nodes upon calling .save(). Saving Nodes to the DB works as expected, but relationships do not appear to be written. Below is an example test that has the issue, along with the node and relationship classes.

Looking through the neo4j web console, the nodes are persisted without relations. Through the debugger, the relationships are in the rangeRelationsOut Sets of a and b nodes, but the relationship's id is null (which should be autogenerated on save).

The most unusual part of this is that it works sometimes. I can re-run the same test without changes, and it will either persist ALL relationships or not persist ANY relationships. I haven't seen any cases where it persists some relationships but not others.

I've seen the same behavior when running the Spring app locally (not tests), but still using the "neo4j:4.2.3" docker container for neo4j. The only fix is to repeatedly restart the Spring app until it decides to work.

Test:

// Neoj4 is running in a TestContainer Docker container.
    @Autowired
    SkuRepository skuRepo;

    @Test
    void testNewRelation() {
        Sku a = new Sku(0L, "A");
        Sku b = new Sku(1L, "B");
        Sku c = new Sku(2L, "C");
        Sku d = new Sku(3L, "D");

        a = skuRepo.save(a);
        b = skuRepo.save(b);
        c = skuRepo.save(c);
        d = skuRepo.save(d);

        a.rangeRelationTo(b, 1, 1 , RelationType.MULTIPLICATIVE);
        a.rangeRelationTo(c, 1, 1 , RelationType.MULTIPLICATIVE);
        a.rangeRelationTo(d, 1, 1 , RelationType.MULTIPLICATIVE);
        a = skuRepo.save(a);

        b = skuRepo.findById(b.getId()).get();
        b.rangeRelationTo(c, 1, 1, RelationType.MULTIPLICATIVE);
        skuRepo.save(b);

        System.out.println("meh!");
    }

Node:

@Node("SKU")
@Getter // lombok
@Setter
public class Sku {

    @Id @GeneratedValue
    private Long id;

    @Property("number")
    private Long number;

    @Property("name")
    private String name;

    @Relationship(type = "RANGE_RELATION_TO", direction = OUTGOING)
    private Set<RangeRelation> rangeRelationsOut = new HashSet<>();

    @ReadOnlyProperty
    @Relationship(type = "RANGE_RELATION_TO", direction = INCOMING)
    private Set<RangeRelation> rangeRelationsIn = new HashSet<>();

    public Sku(Long number, String name) {
        this.number = number;
        this.name = name;
    }


    public RangeRelation rangeRelationTo(Sku sku, double minDelta, double maxDelta, RelationType relationType) {
        RangeRelation relation = new RangeRelation(sku, minDelta, maxDelta, relationType);
        rangeRelationsOut.add(relation);
        return relation;
    }

Relationship:

@Data // lombok
@RelationshipProperties
public class RangeRelation {
    @Id @GeneratedValue private Long id;

    @Property private double minDelta;
    @Property private double maxDelta;
    @Property private RelationType relationType;

    @TargetNode private Sku targetSku;

    public RangeRelation(Sku targetSku, double minDelta, double maxDelta, RelationType relationType) {
        this.targetSku = targetSku;
        this.minDelta = minDelta;
        this.maxDelta = maxDelta;
        this.relationType = relationType;
    }

Repository:

@Repository
public interface SkuRepository extends Neo4jRepository<Sku, Long> {

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions