在Java SpringBoot中,您是否可以拥有通用的起始节点并在以后分配类型?

时间:2017-09-29 23:14:52

标签: java generics spring-boot neo4j relationship

我使用Java SpringBoot和Neo4j作为数据库。

我想用通用的StartNode声明一个RelationshipEntity。 然后,当我创建对象时,我将传递我希望关系绑定到的NodeEntity。

如何进行关系类,因此我不会为每个开始/结束节点类型复制。

示例:

@RelationshipEntity(type = "RESIDES_AT")
public class ResidesAt {

    @StartNode
    private Object startNode; //Can be Company or Person
        ...
    @EndNode
    private Address address;
}

然后在Person and Company Node类中我有:

 @NodeEntity (label="Company")
    public class Company {
        @Relationship(type="RESIDES_AT", direction=Relationship.OUTGOING)
        Set<ResidesAt> residesAt = new HashSet<>();
...
    }

在执行中我会做类似的事情:

Company createCompany = new Company("Top Mechanic");
Person createPerson = new Person("John", "Doe");
Address createAddress = new Address("John's Home", "123 Mystery Lane", null, "Big City", "UT", "84123", null, "Occupied");
createPerson.residesAt(createAddress, "Home Owner");
createCompany.residesAt(createAddress, "John's Business Mailing Address");

companyRepository.save(createCompany); 
personRepository.save(createPerson);

然而;当我尝试启动SpringBoot应用程序时,我收到以下错误:

2017-09-29 16:26:26.832  WARN 7564 --- [           main] org.neo4j.ogm.metadata.ClassInfo         : Failed to find an @StartNode on trn.justin.model.relationships.ResidesAt
2017-09-29 16:26:26.832  WARN 7564 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'companyService': Unsatisfied dependency expressed through field 'companyRepository'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'companyRepository': Unsatisfied dependency expressed through method 'setSession' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.data.neo4j.transaction.SharedSessionCreator#0': Cannot resolve reference to bean 'sessionFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/neo4j/Neo4jDataAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.neo4j.ogm.session.SessionFactory]: Factory method 'sessionFactory' threw exception; nested exception is java.lang.NullPointerException
2017-09-29 16:26:26.832  INFO 7564 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2017-09-29 16:26:26.848  WARN 7564 --- [           main] o.s.b.c.e.EventPublishingRunListener     : Error calling ApplicationEventListener

java.lang.ClassCastException: org.springframework.boot.context.event.ApplicationFailedEvent cannot be cast to org.springframework.boot.web.context.WebServerInitializedEvent

1 个答案:

答案 0 :(得分:0)

我能找到的最佳解决方案是重组事物,以便&#34; NodeEntity&#34;使用&#34; RelationshipEntity&#34; class,RelationshipEntity类使用&#34; RelationshipType&#34; class,并让RelationshipType类包含公共属性。 例如:

@NodeEntity (label="Company")
public class Company {
    ...

    @Relationship(type="RESIDES_AT", direction=Relationship.OUTGOING)
    Set<CompanyResidesAtAddress> residesAt = new HashSet<>();
}

@NodeEntity (label="Address")
public class Address {
   ...
   @Relationship(type="RESIDES_AT", direction=Relationship.INCOMING)
   Set<PersonResidesAtAddress> personResidances = new HashSet<>();

   @Relationship(type="RESIDES_AT", direction=Relationship.INCOMING)
   Set<CompanyResidesAtAddress> companyResidances = new HashSet<>();
}

@RelationshipEntity(type = "RESIDES_AT")
public class CompanyResidesAtAddress {
   ...
   @StartNode
   private Company startNode;

   private ResidesAt residesAt;

   @EndNode
   private Address address;
}

public class ResidesAt implements RelationshipType{

   ... // Common Attributes & methods

   @Override
   public String name() {
      return this.getClass().getSimpleName().toUpperCase();
   }
}

然后在执行中我做了这样的事情:

    Company createCompany = new Company("Top Mechanic");
    Person createPerson = new Person("John", "Doe");
    Address createAddress = new Address("John's Home", "123 Mystery Lane", null, "Salt Lake City", "UT", "84120", null, "Occupied");
    createCompany.residesAt(createAddress, "John's Business Mailing Address");
    createPerson.residesAt(createAddress, "Home Owner");

    companyRepository.save(createCompany); 
    personRepository.save(createPerson);

这对我有用,似乎是我能找到的最佳方式。