I'm modeling my first Spring Data Neo4j app and am wondering about subclassing @RelationshipEntity classes- 1) can it be done, and 2) is it a good idea?
Here's an example of what I'm thinking of using RSS.
A Feed
has many Entry
s and there are 3 types of entry:
A Feed could look like this:
@Relationship
List<Entry> entries;
where Liked is a subclass of Reblog which is a subclass of Entry.
This seems more natural given RelationshipEntities are first class objects:
@Relationship(type="Content", Relationship.OUTGOING)
List<Entry> entries;
...
@RelationshipEntity(type="Content")
public class Content {
...
@RelationshipEntity(type="RebloggedContent")
public class RebloggedContent extends Content {
...
@RelationshipEntity(type="LikedContent")
public class LikedContent extends Content {
...
As I said, this is my first Neo4j app so I don't know if any of these ideas are any good.
From a query point of view I want to be ask questions about both particular types (or combinations of types) of Entry
and Entry
s as a whole.
Pointers to design/modeling ideas are appreciated.
It is possible to sub-class relationship entities with the following caveat:
Example:
Here's an example (in the Kotlin JVM language) of a base relationship entity:
abstract class Relationship
{
@GraphId
internal var graphId: Long?
private set
@StartNode
var auditioner: CandidateProfile
@EndNode
var auditionee: CandidateProfile
var createdDate: Date
init
{
this.graphId = null
this.auditioner = CandidateProfile()
this.auditionee = CandidateProfile()
this.createdDate = Date()
}
abstract fun mutualRelationship(): Relationship?
}
Along with a sub-class:
@RelationshipEntity(type = "MAYBE_LATER")
class MaybeLater constructor(auditioner: CandidateProfile,
auditionee: CandidateProfile,
timeOut: Date?) : Relationship()
{
var timeOut: Date?
var count: Int
init
{
this.auditioner = auditioner
this.auditionee = auditionee
this.timeOut = timeOut
this.count = 1
}
//Provide default constructor for OGM
constructor() : this(CandidateProfile(), CandidateProfile(), null)
override fun mutualRelationship(): MaybeLater?
{
return auditionee.maybeLaters.find { it.auditionee == auditioner }
}
}
Usage:
class CandidateProfile {
@Relationship(type = "LIKES", direction = Relationship.OUTGOING)
var likes: MutableSet<Like>
@Relationship(type = "DISLIKES", direction = Relationship.OUTGOING)
var dislikes: MutableSet<Dislike>
@Relationship(type = "MAYBE_LATER", direction = Relationship.OUTGOING)
var maybeLaters: MutableSet<MaybeLater>
}
Note that we define a collection for each separate relationship type. If a single aggregated collection is required, this needs to be done in code.
Neo4j Users Slack Channel:
In addition to StackOverflow, the Neo4j community provides support via the Neo4j Users public Slack channel - joining is highly encouraged.