Dagmar
Dagmar

Reputation: 3281

Neo4j bug/issue retrieving a relationship when specifying query depth of 2

I am working on a Spring Boot application using Neo4j as the database. I have a UserEntity class that has a relationship with UserContactEntity.

However, when I run a query to fetch UserEntity along with its contacts (depth=2), the contacts field is always null.

Here are the relevant parts of my code:

UserEntity.kt:

import org.neo4j.ogm.annotation.*
import org.springframework.data.neo4j.annotation.Depth
import org.springframework.data.neo4j.annotation.Query
import org.springframework.data.neo4j.repository.Neo4jRepository
import org.springframework.data.repository.query.Param
...
@NodeEntity("User")
class UserEntity : PermissionableEntity, Serializable {
    @Id
    @Property("userId")
    var userId: StringID? = null

    @Relationship("PERSON_HAS_CONTACT")
    var contacts: MutableSet<UserContactEntity> = mutableSetOf()

    // Other fields and methods...
}

UserContactEntity.kt:

import org.neo4j.ogm.annotation.Id
import org.neo4j.ogm.annotation.NodeEntity
import org.neo4j.ogm.annotation.Property
import org.springframework.data.neo4j.annotation.Query
import org.springframework.data.neo4j.repository.Neo4jRepository
import org.springframework.data.repository.query.Param
...
@NodeEntity("UserContact")
class UserContactEntity : Serializable {
    // Fields and methods...
}

UserRepository.kt:

interface UserRepository : Neo4jRepository<UserEntity, StringID> {

    fun findByUserIdIn(userIds: Collection<StringID>, @Depth depth: Int = 2): Iterable<UserEntity>
    
}

I have confirmed that contact data exists, and is correctly associated with the user, by running this query in the Neo4j browser:

MATCH (u:User)-[r:PERSON_HAS_CONTACT]->(c:UserContact)
RETURN u.userId AS userId, c.id AS contactId, c.type AS contactType, c.detail AS contactDetail, c.verified AS contactVerified

I believe I have identified the issue in the logs which show that the generated query uses the wrong relationship mappings. It uses CONTACTS instead of PERSON_HAS_CONTACT and also maps some other relationships that aren't defined in UserEntity.

[.0-8080-exec-10] o.s.d.n.r.query.PartTreeNeo4jQuery       : Executing query for method findByUserIdIn
[.0-8080-exec-10] o.n.o.drivers.bolt.request.BoltRequest   : Request: MATCH (n:`User`) WHERE n.`userId` IN $`userId_0` WITH n RETURN n,[ [ (n)-[r_m1:`MEMBER_FIELDS`]-(f1:`FieldValue`) | [ r_m1, f1, [ [ (f1)-[r_d2:`DEFINITION`]-(f2:`FieldDefinition`) | [ r_d2, f2 ] ] ] ] ], [ (n)-[r_c1:`CONTACTS`]-(u1:`UserContact`) | [ r_c1, u1 ] ] ], ID(n) with params {userId_0=[b3c98b44f2e005250b23a4b02938e9f6, fd587ab3096750e10e5c9a0de61c12bb]}

I have created a custom query that has solved the issue, and I am using as a workaround for now.

@Query("MATCH (u:User)-[:PERSON_HAS_CONTACT]->(c:UserContact)WHERE u.userId IN \$userIds WITH u, collect(c) AS contacts RETURN u, [ [ (u)-[r:`PERSON_HAS_CONTACT`]->(c) | [ r, c ] ] ], ID(u)")
fun findByUserIdInWithContacts(@Param("userIds") userIds: Collection<StringID>): Iterable<UserEntity>

I am still concerned that the default query repository method does not work and that it uses relationships that seem to be coming from somewhere else.

I cannot find a relationship CONTACTS or MEMBER_FIELDS defined in my codebase or in the database.

MATCH (u:User)-[r]->(n)
RETURN type(r) AS relationshipType, count(r) AS count, labels(n) AS targetLabels
ORDER BY count DESC

Returns

relationshipType         count  targetLabels
"USER_HAS_ROLES"            11  ["SystemRole"]
"USER_HAS_CREDENTIALS"      5   ["Credentials"]
"PERSON_HAS_CONTACT"        5   ["UserContact"]
"MARKER_HAS_CREDIBILITY"    1   ["ActiveCompetition"]

I checked the Spring Data Neo4j documentation and didn't find any other way to define relationships.

I have cleaned my local repository and the build to ensure that there is no dead or old code floating around somewhere.

rm -rf ~/.m2/repository/org/my/app
./gradlew clean bootRun | tee output.log  

I have a similar entity for Organisation and it is able to load its relationships when using the default queries, so this is something specific to this user entity.

My questions:

  1. Are there any known issues with Spring Data Neo4j or Neo4j?
  2. Is there some other way of defining relationships be interfering with my code?
  3. Could a bug somewhere else in my application be causing this issue?

Versions:

Upvotes: 0

Views: 82

Answers (0)

Related Questions