Search code examples
springneo4jlabelrelationshipspring-data-neo4j

With Spring's neo4j data how can I update a node with a given label through different classes?


My application updates a node with relationships at different times during application lifecycle. For the earlier life cycle I already have a class that manages my n:First, and its relationships with n2:Second, n3:Third and n4:Fourth.

Now at a later point in the application I need to add further relationships to n:First: relationships with n5:Five and n6:Six; ideally I would use a different class (since that matches the use case) with the same @Node("First") annotation and only those relationships, but I get the error that I cannot instantiate the repository for that class because the label has already been registered.

Is there any way for me to use two different data classes to update the same node, or will I have to go direct to the query? I prefer not to use one massive class that manages six relationships, partly for maintenance, and partly because if I have am writing for a use case that does not require managing relationships for labels Two, Three and Four then I would rather not have to use a data class that has these relationships manifested (and vice versa for Five / Six).

Part of it is paranoia (e.g.: if i save the collection as empty, will it then go and remove all my relationships). Why do I need to go and fetch that node and all the existing relationships if they are not going to be used.


Solution

  • You can do this by using projections.

    By using projections you can just write (or read) a subset of your nodes. Let's take this as an example:

    @Node("product")
    public class Product {
    
        @Id
        private String sku;
        private String name;
        private String description;
    
        @Relationship(type = "SOLD_BY")
        private Set<Shop> shops = new HashSet<>();
    
        @Relationship(type = "COMPATIBLE_WITH")
        private Set<Product> compatibleProducts = new HashSet<>();
    
        @Relationship(type = "REQUIRES")
        private Set<Product> requiredProducts = new HashSet<>();
    
        ...
    

    We have a complex node called product right here. It has different properties and multiple relations. But let's say we only want to update the name of the product node. We can do this by using a projection:

    class ProductWithName {
        private String sku;
        private String name;
        ...
    }
    
    var productWithNewName = new ProductWithName("123", "My new name");
    neo4jTemplate.save(Product.class).one(productWithNewName);
    

    This will only update the name of the product.

    Projections can also be used to query data and can be much more complicated as this example. The documentation will help you.