@RelationshipEntity binding issue


(Neil M. A. Namoro) #1

Okay, so I have an entity called Schedule and it has an attribute which is a list of Volunteer entities called "volunteers". The Volunteer entity is annotated with @RelationshipEntity. I have been trying to retrieve a list of Schedule entities thru a Repository extending the Neo4jRepository class, but when the list of Schedules is retrieved, the volunteers attribute is always empty, even though when testing the query manually using the Neo4j browser the expected result set is there.

Originally, the relationship was much simpler, Schedule entity had a property of a collection of User entities called volunteers, and the Repository query I wrote easily retrieves the Schedules and map the retrieved Users to the volunteers attribute. But when I changed the relationship to a new Volunteer class annotated with @RelationshipEntity, the query doesn't map the retrieved relationship entries to the volunteers attribute.

I know that the cypher queries are correct because I have tested them in the Neo4j browser and it correctly retrieves the result set that I need.

I also tried creating a Repository method that will retrieve only the Volunteer entities, but it also just return empty collections.

I am currently using the following related libraries:

  • spring-boot version 2.1.2.RELEASE
  • spring-boot-starter-data-neo4j 2.1.2.RELEASE
  • neo4j-ogm-core 3.1.6
  • neo4j-ogm-api 3.1.6

I am also using Lombok to generate getters, setters, equals, and hashcode.

This is the Schedule entity POJO:

@Data
@EqualsAndHashCode(callSuper = false, exclude = "volunteers")
@NodeEntity
public class Schedule {

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

    private String description;

    private Date startTime;

    private Date endTime;

    @Relationship(type = "VOLUNTEERED", direction = Relationship.INCOMING)
    private Set<Volunteer> volunteers = new HashSet<>();

    public void addVolunteer(Volunteer volunteer){
        if (volunteer != null && this.volunteers != null){
            this.volunteers.add(volunteer);
        }
    }
}

This is the POJO holding the relationship details:

@Data
@EqualsAndHashCode(callSuper = false, exclude = "schedule")
@RelationshipEntity(type = "VOLUNTEERED")
public class Volunteer {

    public Volunteer(Schedule schedule, User user){
        this.schedule = schedule;
        this.user = user;
        this.signUpDate = new Date();
    }

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

    @StartNode
    private Schedule schedule;

    @EndNode
    private User user;

    private Date signUpDate;

}

This is the Repository code that retrieves the list of Schedules that I need:

@Query("MATCH(s:Schedule)<-[v:VOLUNTEERED]-(u:User) " +
        "WHERE u.uuid = {userUuid} return s, v, u")
List<Schedule> findSchedulesByVolunteer(@Param("userUuid") String userUuid);

This is the Repository code that supposes to retrieve the list of Volunteer objects that I need:

@Query("MATCH(s:Schedule)<-[v:VOLUNTEERED]-(u:User) " +
        "WHERE s.uuid = {schedUuid} return v")
Set<Volunteer> findVolunteersBySchedule(@Param("schedUuid") String schedUuid);

(Gerrit Meier) #2

Hi, I assume that I know where your problem is. The browser is a little bit more user-friendly and e.g. shows the related nodes in for the second query.
That said, the

MATCH(s:Schedule)<-[v:VOLUNTEERED]-(u:User) WHERE s.uuid = {schedUuid} return v

query only returns the VOLUNTEERED relationship v over the wire. This means that Neo4j-OGM does not have any contextual nodes to create the RelationshipEntity Volunteer. It needs also the Schedules and the Users in the result set.