Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
156 views
in Technique[技术] by (71.8m points)

Neo4j SDN4 OGM AmbiguousBaseClassException

I am running into an issue wherein some of my Neo4J queries like the one below ends up in an OGM AmbiguousBaseClassException while others don't. For example findByTitle for the movie "The Score" throws an exception but "The Matrix" does not. My graph is populated by the Movie Database found at https://neo4j.com/developer/example-data/

I am unable to find an explanation to the above observation and I hope someone can help.

curl http://localhost:8080/movies/search/findByTitle?title=The%20Score

Neo4j Server: 3.1.0

Spring-data-neo4j:4.1.1

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.neo4j.ogm.exception.MappingException: Error mapping GraphModel to instance of com.knowledgeGraph.kgClient.domain.Movie
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:982) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) ~[tomcat-embed-core-8.0.28.jar:8.0.28]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) ~[tomcat-embed-core-8.0.28.jar:8.0.28]

Caused by: org.neo4j.ogm.exception.AmbiguousBaseClassException: Multiple classes found in type hierarchy that map to: [Person, Actor, Director]
at org.neo4j.ogm.MetaData.resolve(MetaData.java:174) ~[neo4j-ogm-core-2.0.1.jar:na]
at org.neo4j.ogm.annotations.EntityFactory.resolve(EntityFactory.java:121) ~[neo4j-ogm-core-2.0.1.jar:na]
at org.neo4j.ogm.annotations.EntityFactory.instantiateObjectFromTaxa(EntityFactory.java:105) ~[neo4j-ogm-core-2.0.1.jar:na]
at org.neo4j.ogm.annotations.EntityFactory.newObject(EntityFactory.java:61) ~[neo4j-ogm-core-2.0.1.jar:na]

Domain Objects:

Movie Class:

import static org.neo4j.graphdb.Direction.INCOMING;
import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.voodoodyne.jackson.jsog.JSOGGenerator;

@JsonIdentityInfo(generator=JSOGGenerator.class)
@NodeEntity
@JsonIgnoreProperties(ignoreUnknown = true)
public class Movie {

@GraphId Long nodeId;
String id;
String title;
String description;

@Relationship(type="DIRECTED", direction = Relationship.INCOMING)
List<Person> directors;

@Relationship(type="ACTS_IN", direction = Relationship.INCOMING)
List<Person> actors;

private String language;
private String imdbId;
private String tagline;
private String releaseDate;
private Integer runtime;
private String homepage;
private String trailer;
private String genre;
private String studio;
private Integer version;
private String lastModified;
private String imageUrl;

public Movie() { }

public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}

/*Remaining Set's and Get's*/

}

Person Class:

import org.neo4j.ogm.annotation.GraphId;
import org.neo4j.ogm.annotation.NodeEntity;
import com.fasterxml.jackson.annotation.JsonSubTypes;

@NodeEntity
@JsonSubTypes({
@JsonSubTypes.Type(value = Actor.class, name = "actor"),
@JsonSubTypes.Type(value = Director.class, name = "director")
})

public class Person {

    @GraphId Long nodeId;
    String id;
    String name;
    private String birthday;
    private String birthplace;
    private String biography;
    private Integer version;
    private String lastModified;
    private String profileImageUrl;

    public Person () {}

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

    /*Remaining Set's and Get's*/

}

Director Class:

@NodeEntity
public class Director extends Person{

@GraphId
Long id;

public Director() {
}

@Relationship(type="DIRECTED", direction = Relationship.OUTGOING)
private List<Movie> directedMovies = new ArrayList<Movie>();

public List<Movie> getDirectedMovies() {
    return directedMovies;
}

public void setDirectedMovies(List<Movie> directedMovies) {
    this.directedMovies = directedMovies;
}

}

Actor Class:

@NodeEntity
public class Actor extends Person {

@GraphId
Long id;

public Actor() {
}

@Relationship(type="ACTS_IN", direction = Relationship.OUTGOING)
private List<Movie> actedMovies = new ArrayList<Movie>();

public List<Movie> getMovies() {
    return actedMovies;
}

public void setMovies(List<Movie> movies) {
    this.actedMovies = movies;
}
}

Repositories:

public interface ActorRepository extends GraphRepository<Actor>{

    @Query("MATCH (a:Actor) -[:ACTS_IN]-> (m:Movie {`title`:{title}}) return a")
    Collection<Actor> findActorsOfMovie(@Param("title") String title);
}


public interface DirectorRepository extends GraphRepository<Director>{

    @Query("MATCH (d:Director) -[:DIRECTED]-> (m:Movie {`title`:{title}}) return d")
    Collection<Director> findDirectorOfMovie(@Param("title") String title);

}

public interface MovieRepository extends GraphRepository<Movie>{

    Movie findByTitle(@Param("title") String title);

    @Query("MATCH (m:Movie) WHERE m.title =~ ('(?i).*'+{title}+'.*') RETURN m")
    Collection<Movie> findByTitleContaining(@Param("title") String title);
}

public interface PersonRepository extends GraphRepository<Person>{

    @Query("MATCH (a:Person) -[:ACTS_IN]-> (m:Movie {`title`:{title}}) return a")
    Set<Person> findActorsOfMovie(@Param("title") String title);

    @Query("MATCH (d:Person) -[:DIRECTED]-> (m:Movie {`title`:{title}}) return d")
    Set<Person> findDirectorOfMovie(@Param("title") String title);
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Resolved this problem by removing Actor and Director domain classes and used Person class with Actor list and director list.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...