Say I have nodes of types A, B and C, and I have the following graph:
@NodeEntity
data class A(
@Id val id: String? = null,
@Relationship(type = "HAS_B")
val b: MutableSet<B> = mutableSetOf<B>()
)
@RelationshipEntity(type = "HAS_B")
data class HasB @JvmOverloads constructor(
@Id @GeneratedValue val id: Long? = null,
@StartNode val start: A = A(),
@EndNode val end: B = B()
)
@NodeEntity
data class B(
@Id val id: String? = null,
@Relationship(type = "HAS_C")
val c: MutableSet<C> = mutableSetOf<C>()
)
...
My goal is to load the node A, together with the connected B and C nodes.
Currently (in Kotlin code) I am doing session.load(A::class.java, "a1", -1)
, which uses this implementation:
<T,ID extends Serializable> T load(Class<T> type, ID id, int depth)
(from here)
Supposedly, with depth = -1, this should load node A together with all its connected nodes. However, it seems to only load the node A.
What is causing this issue, and how to fix it?
Note: I have edited the question to better reflect the essence of it. This answer summarizes the learnings from https://github.com/neo4j/neo4j-ogm/issues/951, which is mainly contributed by https://stackoverflow.com/users/2650436/meistermeier
What's causing the issue is:
@Relationship(type = "HAS_B")
val b: MutableSet<B> = mutableSetOf<B>()
In order for OGM to go from node entity A
to relationship entity HasB
, the @Relationship
should annotate a variable that directly refers to the relationship entity itself, instead of node entity B (i.e. the node entity it connects A to).
Solution:
@NodeEntity
data class A(
@Id val id: String? = null,
@Relationship(type = "HAS_B")
var b: MutableSet<HasB> = mutableSetOf()
)
@RelationshipEntity(type = "HAS_B")
class HasB @JvmOverloads constructor(
@Id @GeneratedValue val id: Long? = null,
@StartNode val start: A = A(),
@EndNode val end: B = B()
) {
override fun toString(): String {
return "HasB(id=$id, end=$end)"
}
}
@NodeEntity
data class B(
@Id val id: String? = null,
@Relationship(type = "HAS_C")
val c: MutableSet<C> = mutableSetOf()
)
@NodeEntity
data class C(
@Id val id: String? = null
)