troig troig - 1 month ago 14
Java Question

Neo4jRepository @Query result error when there are many relationships for same node

Let's suppose we use this simple graph model:

@NodeEntity
class Ad {
// GraphId and more Ad attributes...

@Relationship(type = "HAS_ADVERTISER", direction = Relationship.OUTGOING)
private User advertiser;

@Relationship(type = "IS_FAVOURITE_TO", direction = Relationship.OUTGOING)
private Set<User> favourites = new HashSet<>();

// Getters and setters
}


EDIT: Following the advises of one of the aswers, I've tried adding the incoming relationships to User entity, but the problem still remains.

@NodeEntity
class User {
// User attributes. No incoming relationships for HAS_ADVERTISER neither IS_FAVOURITE_TO...

// EDIT: Added incoming relationships to User entity, but the problem still remains. Tried annotating getters/setters, but neither works
@Relationship(type = "HAS_ADVERTISER", direction = Relationship.INCOMING)
private Set<Ad> ads = new HashSet<>();

@Relationship(type = "IS_FAVOURITE_TO", direction = Relationship.INCOMING)
private Set<Ad> favourites = new HashSet<>();

@Relationship(direction = Relationship.INCOMING)
public Set<Ad> getAds() {
return ads;
}

@Relationship(direction = Relationship.INCOMING)
public void setAds(Set<Ad> ads) {
this.ads = ads;
}

@Relationship(direction = Relationship.INCOMING)
public Set<Ad> getFavourites() {
return favourites;
}

@Relationship(direction = Relationship.INCOMING)
public void setFavourites(Set<Ad> favourites) {
this.favourites = favourites;
}
}


If I execute a cypher query to retrieve the ads with advertiser and favourites information through neo4j console, it's simply working well:

MATCH (ad:Ad),
(ad)-[has_advertiser:HAS_ADVERTISER]->(advertiser:User),
(ad)-[is_favourite_to: IS_FAVOURITE_TO] -> (favouriteUser:User)
return ad, has_advertiser, advertiser, is_favourite_to, favouriteUser


enter image description here

However, if I execute the query through a
neo4jRepository
instead:


  • advertiser
    user is persisted correctly.

  • There are two users in
    favourites
    set: the advertiser user is always added to the set, which is incorrect because there is no
    IS_FAVOURITE_TO
    relationship with this user.






@Repository
public interface AdRepository extends Neo4jRepository<Ad> {

@Query("MATCH (ad:Ad)," +
"(ad)-[has_advertiser:HAS_ADVERTISER]->(advertiser:User)," +
"(ad)-[is_favourite_to: IS_FAVOURITE_TO] -> (favouriteUser:User)" +
"return ad, has_advertiser, advertiser, " +
"is_favourite_to, favouriteUser ")
List<Ad> findAds();
}


enter image description here

Can I change something in my query or my graph model to avoid this?
Maybe a spring-data-neo4j bug?

Versions:

<spring-data-neo4j.version>4.2.0.M1</spring-data-neo4j.version>
<neo4j.ogm.version>2.0.5</neo4j.ogm.version>

Answer

This is due to the fact that the OGM considers this to be an ambiguous model. If you add the incoming relationships to User, your issue should be resolved.

Update: upon further investigation, this is indeed a bug. Opened https://github.com/neo4j/neo4j-ogm/issues/276

The workaround is to annotate all your getters and setters (and make sure the @Relationship annotation contains both the relationship type and the direction) in both Ad and User.