How to model entities with self-relationships?

Hi!
I am very new to Neo4J and graph databases. I am learning by writing simple CRUD operations using SDN-RX.
I want to create a social graph with a structure that reflects this data class:

class Person(
        @Id val name: String,
        val age: Int,
        @Relationship(type = "FRIENDS_WITH") var friendsWith: Set<Person>? = null,    //bidirectional
        @Relationship(type = "FOLLOWS") var follows: Set<Person>? = null   //unidirectional
)

Trying to populate the database with the following code doesn't work:

private fun populate() {
        val a = Person("A", 11)
        val b = Person("B", 22)
        val c = Person("C", 33)
        a.friendsWith = setOf(b, c)
        b.friendsWith = setOf(a)
        c.friendsWith = setOf(a)
        a.follows = setOf(b)
        c.follows = setOf(b)
        peopleRepository.save(p)
    }

Any help or documentation would be appreciated. I cannot find any examples that include relations with same entity type.

There is ongoing work on this topic at the moment: https://github.com/neo4j/sdn-rx/issues/254

It does not work right now because the default relationship direction is outgoing. During the mapping phase the framework follow those and end up in the endless (mapped) loop.

Thank you Gerrit. Is there a temporary workaround to my problem? I thought Neo4J is made for such scenarios and hence was using this example for introducing Neo4J to my team. I am fairly new to SDN-RX, would switching to Neo4J-OGM help?

Yes, we love relationships ;)
The follows relationship looks good because one person follows another one (direction).
The bidirectional / undirected friends_with relationship is something that is modelled "against" the directed relationship nature of Neo4j. All relationships needs to have a direction in the database.
On an application layer (and in this very basic example) it makes sense to have some concept of undirected relationships that lose direction information and just care about the existence.

Neo4j-OGM would work but the successor of Neo4j-OGM and the current Spring Data Neo4j will be SDN-RX.

@gerrit.meier I still can't find examples using SDN-RX that persist bi-directional data. Here's a slightly different example that triggers an infinite loop using SDN-RX 1.1.0:


    data class Employee(@Id @Property("eid") val id: Long,
                    val name: String,
                    val knows: MutableSet<Employee> = mutableSetOf())


    @Transactional
    fun addEmployees(): Flux<Employee> {
        val e2 = Employee(12, "AA")
        val e3 = Employee(13, "BB")
        e2.knows.add(e3)
        e3.knows.add(e2)
        return employeeRepository.saveAll(Flux.just(e2, e3))
    }

There's a lot of documentation for OGM around such relations (using depth parameters). SDN-RX doesn't seem to have any guidelines for beginners like me. Am I missing some essential piece of documentation? I didn't find any note on depth resolution in the manual.

I would love to differentiate between two topics that somehow get mixed right now (also from my side):
Undirected relationships and bidirectional ones.
What you are showing in your code ist a bidirectional one: An outgoing relationship to a node that refers back to the very same node it started from. This is clearly a bug and we have a fix in the pipeline for this https://github.com/neo4j/sdn-rx/pull/263
The other thing that we will introduce are undirected relationships: They store just one (directed) relationship in the database but the queries do not care about the direction but just dismiss this information to have them reachable from each side.

There is no depth limit in SDN/RX in general when it comes to persisting and querying nodes. There are some corner cases like self-references where we draw a line in the query depth to avoid endless loops. https://neo4j.github.io/sdn-rx/current/#relationshipquerylimit

Thank you for explaining the difference! It makes sense now.