title: neo4j ogm ambiguity in relationships using interfaces
body: <p>I'm working with neo4j ogm version 2.1.1 and I am receiving the following error when modelling a relationship between two classes of the same type:</p>
  
  <p>AmbiguousBaseClassException: Multiple classes found in type hierarchy that map to: [Package, Namespace, TypedElement, PackageableElement, NamedElement, Element, NetworkNode]</p>
  
  <p>My scenario is that I have multiple classes that implement the PackageableElement interface, such as a package and a class. The relationship of a PackageableElement can have one or more PackageableElements exits. </p>
  
  <p>Eg. A Package contains many Classes. The relationship seems to persist ok, but upon retrieval the error above is thrown. </p>
  
  <p>Reading the docs, if I have understood the "ambiguity in relationships" issue, I have modified the relationship in this case with Package to use the type of "UNDIRECTED" so that the relationship is navigable in both directions. This has not solved the problem. I've pasted 3 domain objects below to show my relationship. </p>
  
  <p>The structure is a Package inherits from Namespace, which implements the PackageableElement interface which has the method and annotation:
  @org.neo4j.ogm.annotation.Relationship(type = "HasPackageableElement", direction = org.neo4j.ogm.annotation.Relationship.UNDIRECTED)
      public Set getPackageableElements();</p>
  
  <p>Package entity</p>
  
  <pre><code>@NodeEntity
  @JsonTypeName("Package")
  public class Package extends Namespace {
  
  public String getURI() {
      return URI;
  }
  
  public void setURI(String URI) {
      this.URI = URI;
  }
  
  String URI;
  
  @Override
  public Integer getSequence() {
      return sequence;
  }
  
  @Override
  public void setSequence(Integer sequence) {
      this.sequence = sequence;
  }
  
  @Index
  Integer sequence;
  </code></pre>
  
  <p>}</p>
  
  <p>Namespace class</p>
  
  <pre><code>@NodeEntity
  public class Namespace implements PackagebleElement {
  
  @Override
  public Long getId() {
      return id;
  }
  
  @Override
  public void setId(Long id) {
      this.id = id;
  }
  
  @GraphId
  private Long id;
  
  @Override
  public Set&lt;Comment&gt; getComments() {
      return comments;
  }
  
  @Override
  public void setComments(Set&lt;Comment&gt; comments) {
      this.comments = comments;
  }
  
  private Package owningPackage;
  
  @Override
  public Package getOwningPackage() {
      return owningPackage;
  }
  
  @org.neo4j.ogm.annotation.Relationship(type = "HAS_COMMENT", direction = org.neo4j.ogm.annotation.Relationship.OUTGOING)
  Set&lt;Comment&gt; comments;
  
  @Override
  public String getName() {
      return name;
  }
  
  @Override
  public void setName(String name) {
      this.name = name;
  }
  
  @Index
  private String name;
  
  @Override
  public VisibilityKindEnum getVisibility() {
      return visibility;
  }
  
  @Override
  public void setVisibility(VisibilityKindEnum visibility) {
      this.visibility = visibility;
  }
  
  private VisibilityKindEnum visibility;
  
  Object type;
  
  @Override
  public Object getType() {
      return type;
  }
  
  @Override
  public void setType(Object type) {
      this.type = type;
  }
  
  @Override
  public Integer getSequence() {
      return sequence;
  }
  
  @Override
  public void setSequence(Integer sequence) {
      this.sequence = sequence;
  }
  
  @Index
  Integer sequence;
  
  public static enum ElementTypeEnum {
  
      Class,
      Package;
  }
  
  @Override
  public Set&lt;PackageableElement&gt; getPackageableElements() {
      if (packageableElements == null)
          packageableElements = new HashSet&lt;PackageableElement&gt;();
      return packageableElements;
  }
  
  @org.neo4j.ogm.annotation.Relationship(type = "HasPackageableElement", direction = Relationship.UNDIRECTED)
  public void setPackageableElements(Set&lt;PackageableElement&gt; packageableElements) {
      this.packageableElements = packageableElements;
  }
  
  @org.neo4j.ogm.annotation.Relationship(type = "HasPackageableElement", direction = Relationship.UNDIRECTED)
  Set&lt;PackageableElement&gt; packageableElements;
  }
  </code></pre>
  
  <p>PackageableElement class</p>
  
  <pre><code>@NodeEntity
  public interface PackageableElement extends NamedElement {
  
  @org.neo4j.ogm.annotation.Relationship(type = "HasPackageableElement", direction = org.neo4j.ogm.annotation.Relationship.UNDIRECTED)
  public Set&lt;PackageableElement&gt; getPackageableElements();
  
  public Integer getSequence();
  
  public void setSequence(Integer sequence);
  
  }
  </code></pre>
  
  <p>I've debugged the resolve method of the MetaData class in ogm and it appears to be a bug to me. The line which reads 
  if (taxonClassInfo.isInterface()) {
                      LOGGER.debug("label is on an interface. Looking for a single implementing class...");
                      taxonClassInfo = findSingleImplementor(taxon);</p>
  
  <p>The findSingleImplementor method is returning results where I have an interface extending another interface. In my scenario, NamedElement interface extends Element interface. This is then adding an > 1 entry to the resolved array which is then throwing the error.</p>
  
  <p>Is this the correct behaviour? I would've thought it should be looking for concrete implementations.</p>