Neo4j RelationshipEntity not persisted

Hi everyone, I'm having some issues getting a neo4j RelationshipEntity persisted with neo4j and Spring Boot.

I have a simple NodeEntity, which contains a collection for the RelationshipEntity:

@NodeEntity
public class Book {
    @Id
    @GeneratedValue
    private Long id;
    private String name;

    public Book() {}

    public Book(String name) {
        this.name = name;
    }

    @Relationship(type = "PURCHASED_WITH", direction = "OUTGOING")
    private Set<BookPurchase> purchases = new HashSet<>();

    // getters and setters follow
}

I have another NodeEntity, which also contains a collection for the relationship entity:

@NodeEntity
public class CreditCard {

    @Id
    @GeneratedValue
    private Long id;
    private String number;

    @DateString(value = "yyyy-MM-dd")
    private Date expiryDate;

    public CreditCard() {}

    public CreditCard(String number, Date expiryDate) {
        this.number = number;
        this.expiryDate = expiryDate;
    }

    @Relationship(type = "PURCHASED_WITH", direction = "INCOMING")
    private Set<BookPurchase> purchases = new HashSet<BookPurchase>(); 

    // getters and setters follow
}

I have the RelationshipEntity, which adds references to both NodeEntity classes in the constructor:

@RelationshipEntity(type = "PURCHASED_WITH")
public class BookPurchase {
    @Id
    @GeneratedValue
    private long id;

    @DateString("yyyy-MM-dd")
    Date purchaseDate;

    @StartNode
    private Book book;

    @EndNode
    private CreditCard card;

    public BookPurchase(){}

    public BookPurchase(CreditCard card, Book book, Date purchaseDate) {
        this.card = card;
        this.book = book;
        this.purchaseDate = purchaseDate;

        this.card.getPurchases().add(this);
        this.book.getPurchases().add(this);
    }
    // getters and setters follow
}

And finally I have the Spring controller tying everything together:

@RestController
public class ExamplesController {

    @Autowired
    CreditCardRepository creditCardRepository;

    @PostMapping(value="/purchases")
    public String createPurchases() {
        CreditCard card = new CreditCard("11111", new GregorianCalendar(2018, Calendar.FEBRUARY, 12).getTime());

        Book book1 = new Book("of mice and men");
        BookPurchase purchase1 = new BookPurchase(card,book1,new GregorianCalendar(2018, Calendar.MARCH, 15).getTime());

        creditCardRepository.save(card);
        return "Successfully created entities";
    }
}

Whenever I try to curl -X POST http://localhost:8080/purchases , I just see the following in the neo4j browser - the RelationshipEntity is not persisted, only the nodes.

Can anyone assist?

The problem is that you are using a long instead of the object/wrapper type Long in your BookPurchase. Neo4j-OGM assumes that the relationship entity already exists in the database because it has a non-null value (primitive long defaults to 0).
Using the Long type will fix your problem.

1 Like

Thanks very much @gerrit.meier, that was exactly it!

Could you please set the solved checkmark? It helps others to navigate better to a solution.

Hi @gerrit.meier I have 'Node' entities as

public class Clusstre extends BasicDomain{

'Index'
'NotNull'
'NotEmpty'
private String uid;

'NotNull'
'NotEmpty'
private String name;

'Relationship(type = "CONNECTED", direction = Relationship.INCOMING)'
private Set<Connection> connections = new HashSet<Connection>();

public Clusstre(String uid) {
    this.uid = uid;
}

public Clusstre(String id, String uid, String name) {
    super(id);
    this.uid = uid;
    this.name = name;
}

public Clusstre(String uid, String name) {
    this.uid = uid;
    this.name = name;
}

}

'NodeEntity'
'Getter'
'Setter'
'EqualsAndHashCode'
NoArgsConstructor
AllArgsConstructor
public class User extends BasicDomain{

Index
private  Long uid;

Index
private String email;

Relationship(type = "CONNECTED" )
private Set<Connection> connections = new HashSet<Connection>();

public User( String email) {
    this.email = email;
}

public User(Long uid, String email) {
    this.uid = uid;
    this.email = email;
}

public User(String id, Long uid, String email) {
    super(id);
    this.uid = uid;
    this.email = email;
}

}

and 'RelationshipEntity'

RelationshipEntity(type = "CONNECTED")
Getter Setter

public class Connection extends BasicDomain{

StartNode
private Clusstre clusstre;

EndNode
private User user;

 Property
private LocalDateTime connectionOn;

public Connection(Clusstre clusstre, User user) {
    super();
    this.clusstre = clusstre;
    this.user = user;
    this.connectionOn = java.time.LocalDateTime.now();
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof Connection)) return false;
    Connection that = (Connection) o;
    return getClusstre().equals(that.getClusstre()) &&
            getUser().equals(that.getUser());
}


public int hashCode() {
    return Objects.hash(getClusstre(), getUser());
}

}


I have already persisted both 'NodeEntiy' and after that storing 'RelationshipEntity'
it establish connection also I can see in graph connected both entities.

But the problem is When try to fetch (using userRepository.findByUid or clusstreRepository.findByUid) I can't get connections data , rest of attributes fetches properly.

Please suggest solution.

public class BasicDomain {

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

}

FYI - I also noticed that if one were to accidentally set this to final, then this RelationshipEntity will not be persisted as well.