如何使节点成为多种类型?

时间:2014-04-15 20:44:29

标签: neo4j spring-data-neo4j

我正在做一个测试电影项目来学习neo4j和SDN,这是我面临的一个问题:

如你所知,电影导演可能是制片人或作家,甚至是演员。在我的 java 类架构中,我有 Person 超类。它有孩子:制片人,导演,演员作家。所有这些子节点都处于同一级别,因此它们是不兼容的类型。

另一方面,在 neo4j 中,我的节点同时是Producer,Director和Writer。

example of node that has several labels
因此,当我想通过repository.findAll()方法(或通过Cypher查询的自定义方法)获取所有控制器时,我遇到了问题。春天告诉我:

  

java.lang.IllegalArgumentException:无法设置java.util.Set字段   com.test.db.domain.Producer.producedMovies to   com.test.db.domain.Director

我使用Neo4j 2.0.1和Spring Data Neo4j 3.0.0.RELEASE。

解决此类问题的正确方法是什么?


更新:
这是代码:

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("service-beans.xml");
        Neo4jTemplate neo4jTemplate = context.getBean(Neo4jTemplate.class);

        DirectorRepository repository = context.getBean(DirectorRepository.class);
        try (Transaction transaction = neo4jTemplate.getGraphDatabase().beginTx()) {
            EndResult<Director> all = repository.findAll_Upd(); //repository.findAll();
            Iterator<Director> iterator = all.iterator();
            while(iterator.hasNext()) {
                System.out.println(iterator.next());
            }
            transaction.success();
        }
    }
}

@Transactional
public interface DirectorRepository extends GraphRepository<Director> {
    @Query("match(n:Director) return n")
    EndResult<Director> findAll_Upd();
}

@NodeEntity
public class Person implements Comparable<Person> {
    @GraphId
    Long nodeId;
//    @Indexed(unique=true)
    String id;
    @Indexed(indexType= IndexType.FULLTEXT, indexName = "people")
    String name;
    private Short born;
    private Date birthday;
    private String birthplace;
    private String biography;
    private Integer version;
    private Date lastModified;
    private String profileImageUrl;
...
}

public class Director extends Person {
    @Fetch @RelatedTo(elementClass = Movie.class, type = RelationshipConstants.DIRECTED)
    private Set<Movie> directedMovies = new HashSet<>();
}

public class Producer extends Person {
    @Fetch @RelatedTo(elementClass = Movie.class, type = RelationshipConstants.PRODUCED)
    private Set<Movie> producedMovies = new HashSet<>();
}

public class Actor extends Person  {
    @RelatedToVia(type = RelationshipConstants.ACTED_IN)
    List<Role> roles;
}

@NodeEntity
public class Movie implements Comparable<Movie> {
    @GraphId
    Long nodeId;    
    @Indexed(unique = true)
    String id;    
    @Indexed(indexType= IndexType.FULLTEXT, indexName = "search")
    String title;    
    int released;    
    String tagline;    
    @Fetch @RelatedTo(type = RelationshipConstants.ACTED_IN, direction = INCOMING)
    Set<Actor> actors;    
    @Fetch @RelatedTo(type = RelationshipConstants.PRODUCED, direction = INCOMING)
    Set<Producer> producers;    
    @RelatedToVia(type = RelationshipConstants.ACTED_IN, direction = INCOMING)
    List<Role> roles;
}

完整的例外:

  

线程中的异常&#34; main&#34;   org.springframework.data.mapping.model.MappingException:设置   属性在Rob Reiner [null]上生成的电影为null   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setProperty(SourceStateTransmitter.java:85)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:91)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access $ 000(SourceStateTransmitter.java:40)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter $ 2.doWithAssociation(SourceStateTransmitter.java:61)     在   org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:291)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityFetchHandler.fetchValue(Neo4jEntityFetchHandler.java:75)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityFetchHandler.fetch(Neo4jEntityFetchHandler.java:60)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl $ 1.doWithAssociation(Neo4jEntityConverterImpl.java:135)     在   org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:291)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.cascadeFetch(Neo4jEntityConverterImpl.java:125)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:114)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:104)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister $ CachedConverter.read(Neo4jEntityPersister.java:170)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)     在   org.springframework.data.neo4j.support.Neo4jTemplate.createEntityFromState(Neo4jTemplate.java:223)     在   org.springframework.data.neo4j.fieldaccess.RelationshipHelper.createEntitySetFromRelationshipEndNodes(RelationshipHelper.java:150)     在   org.springframework.data.neo4j.fieldaccess.RelatedToFieldAccessor.createEntitySetFromRelationshipEndNodes(RelatedToFieldAccessor.java:86)     在   org.springframework.data.neo4j.fieldaccess.RelatedToCollectionFieldAccessorFactory $ RelatedToCollectionFieldAccessor.getValue(RelatedToCollectionFieldAccessorFactory.java:76)     在   org.springframework.data.neo4j.fieldaccess.DefaultEntityState.getValue(DefaultEntityState.java:97)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyEntityStatePropertyValue(SourceStateTransmitter.java:90)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.access $ 000(SourceStateTransmitter.java:40)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter $ 2.doWithAssociation(SourceStateTransmitter.java:61)     在   org.springframework.data.mapping.model.BasicPersistentEntity.doWithAssociations(BasicPersistentEntity.java:291)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.copyPropertiesFrom(SourceStateTransmitter.java:57)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.loadEntity(Neo4jEntityConverterImpl.java:112)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.read(Neo4jEntityConverterImpl.java:104)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister $ CachedConverter.read(Neo4jEntityPersister.java:170)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.createEntityFromState(Neo4jEntityPersister.java:189)     在   org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.projectTo(Neo4jEntityPersister.java:216)     在   org.springframework.data.neo4j.support.Neo4jTemplate.projectTo(Neo4jTemplate.java:240)     在   org.springframework.data.neo4j.support.conversion.EntityResultConverter.doConvert(EntityResultConverter.java:73)     在   org.springframework.data.neo4j.conversion.DefaultConverter.convert(DefaultConverter.java:44)     在   org.springframework.data.neo4j.support.conversion.EntityResultConverter.convert(EntityResultConverter.java:165)     在   org.springframework.data.neo4j.conversion.QueryResultBuilder $ 1.Convert的(QueryResultBuilder.java:103)     在   org.springframework.data.neo4j.conversion.QueryResultBuilder $ 1.访问$ 300(QueryResultBuilder.java:81)     在   org.springframework.data.neo4j.conversion.QueryResultBuilder $ 1 $ 1.underlyingObjectToObject(QueryResultBuilder.java:121)     在   org.neo4j.helpers.collection.IteratorWrapper.next(IteratorWrapper.java:47)     在com.test.util.App.main(App.java:34)at   sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at   sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)     在   sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     在java.lang.reflect.Method.invoke(Method.java:606)at   com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)   引起:java.lang.IllegalArgumentException:无法设置   java.util.Set字段com.test.db.domain.Producer.producedMovies到   com.test.db.domain.Director at   sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164)     在   sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168)     在   sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55)     在   sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75)     在java.lang.reflect.Field.set(Field.java:741)at   org.springframework.util.ReflectionUtils.setField(ReflectionUtils.java:102)     在   org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:90)     在   org.springframework.data.mapping.model.BeanWrapper.setProperty(BeanWrapper.java:68)     在   org.springframework.data.neo4j.support.mapping.SourceStateTransmitter.setProperty(SourceStateTransmitter.java:83)     ... 43更多


更新
我也尝试过projectTo()方法(projections),但我仍然得到同样的异常:

Director director = neo4jTemplate.projectTo(person, Director.class);

1 个答案:

答案 0 :(得分:0)

我不确定neo4j映射 - 但您的java模型与您的业务描述不匹配 - 您更需要具有Set&lt;的Person类。 MovieJob&GT;成员 - 其中MovieJob是您的抽象类,其中Actor,Director,Producer是子类。