cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Inheritance in SDN/RX

scott2
Node Link

A project that I am trying to port to SDN/RX made heavy use of inheritance fo certain objects and the previous version of Neo4j Spring Data happily turned all those classes into Labels.

Now If I try to create a relationship to an abstract class or interface I get an error on save. Is this a bug in the present beta or is polymorphism no longer supported in the new SDN/RX libraries?

18 REPLIES 18

Congratulations you are right in time for a discussion about this and providing us input: https://github.com/neo4j/sdn-rx/issues/147

Our current plan is to discard (or better: not add) the label inheritance that used to exist in Neo4j-OGM. We would like to have one primary labels and x additional ones on a concrete class. This does not mean that you cannot put shared properties in a "base class".
We had this idea because we could avoid looking up the most concrete implementation for each label and as a result have less mapping code to a) maintain and b) that affects the performance.

If I try to create a relationship to an abstract class or interface[...]

We would really like to know what the use case behind this approach is. I could imagine something like Owner has Dog or Cat that you are referring to as Pet (abstract class / interface). Would it be to inconvenient for this case to create multiple same-type relationships on the Owner class?

scott2
Node Link

In my case I have a class called Interval which has multiple implementations (Hour,Day,Month,Year)

Then I have a class called Measurement which references an Interval. Here are some simplified representation of my objects:

public abstract class Interval
{
   Interval( long start, long end )
   {
      this.id=Long.toString(start)+"-"+Long.toString(end);
      this.start = start;
      this.end = end;
   }
   @Id
   public String id;
   public long start;
   public long end;
}

@Node
public class Hour extends Interval
{
    Hour( DateTime dateTime )
    {
       super( dateTime.toMillis(), dateTime.plusHour(1).toMillis());
    }
}

public class Day extends Interval
{
  public Day( DateTime dateTime )
  {
     super( dateTime.toMillis(), dateTime.plusDay(1).toMillis() );
  }
}

public class Measurement
{
   @Id
   @GeneratedValue
   public Long id;

   @Relationship("INTERVAL")
   public Interval interval;
   
   public long value;
}

This code example will throw an exception when I try to save Measurement due to it not being able to determine which ID to use for Interval.

scott2
Node Link

Losing the Automatic Labeling of Object Hierarchies is probably a good thing, however, I have noticed that SDN/RX is also ignoring the labels in the @Node annotation which seems like a bug to me. i.e.:

// the labels here will be ignored:
@Node( "Hour","Interval")
public class Hour extends Interval
{
}

Thanks a lot for your feedback on this topic.
You are right, it is not done yet but we have it on our list (https://github.com/neo4j/sdn-rx/issues/82) and the current plan is to implement it as one of the next items.

I see there is a Pull Request for this feature. Do you know when it is expected to be merged into master and a new maven pom released? I'm quite anxious for this fix!

Maybe tomorrow or Friday 😉
You could also build the branch on your own and see if it fits your need. Feedback is always welcome.

Oh, this was referring to the merge to master and not an actual release.
After the merge we will plan when to release the next preview version.

scott2
Node Link

Awesome! I'm testing it out, but it requires reworking several places in my project to use JARs

You could install it to your local maven repository e.g. as version 1.0.0-multilabel and reference this version in you pom.xml / build.gradle.

I actually tried installing in my local maven repository and then using mavenLocal() in my gradle build, but couldn't get it to work.

I know this is off topic but if anyone has any advice on how to use these maven poms in an existing gradle project i'm listening.

Of course I'm still hoping that beta version 4 gets released today!

scott2
Node Link

So I was able to finally get the code from git to work. The problem of inheritance (the original issue) is still present.

I have been able to work around my issue by hacking the Neo4jMappingContext so that it will ignore abstract classes and classes that are not annotated with @Node. I can share that code with you but I think the actual problem is deeper in the code, somehow the Entity scanning is trying to map domain Classes that are not appropriate when inheritance is used.

What is the best way that I can communicate this issue to you? Would you like me to create a sample project?

Could you create an issue here: https://github.com/neo4j/sdn-rx/issues ? That would be really helpful.

Okay, issue submitted!

scott2
Node Link

BTW, I was wondering if there is a "best" practice for architecting the pattern I described above. Basically is there a way to reference an"Abstract" concept in neo4j.

In my particular example i have the concept of an Interval which has concrete implementations of Hour,Day, Month, Year etc.

I'm curious if anyone things this is a bad implementation and if there is a suggestion for a better way of approaching this issue.

scott2
Node Link

Hey! in the latest beta04 release this appears to be fixed! Great work guys!

Thanks, I was not sure that your problem got also fixed. Great to hear and thanks for your feedback.

Hi
In my code , i have classes A,B,C,D
B, C,D are abstract classes A is concrete one
A->extends ->B->extends -> C ->extends -> D->extends->GraphNode

B, C,D are annoted with @Node with primary label and labels

is it possible to have multilevel inheritance like this?

because A is not mapped with any values and If we remove @Node from B and C and D it is getting proper values

Could you create an example project for this?
Basically the constellation should work as expected without the need to remove any annotation.