2017-09-29 5 views
1

Ich verwende Java SpringBoot und Neo4j als DB.In Java SpringBoot, Können Sie einen generischen Startknoten haben und Typ später zuweisen?

Ich möchte eine BeziehungEntity mit einem generischen StartNode deklarieren. Wenn ich dann das Objekt erstelle, werde ich die NodeEntity übergeben, an die ich die Beziehung binden möchte.

Wie kann ich die Beziehungsklasse tun, damit ich nicht für jeden Start/End-Node-Typ duplizieren.

Beispiel:

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

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

Dann in der Person und Firma Knotenklasse I haben:

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

Und in der Ausführung würde ich so etwas wie:

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); 

jedoch; wenn ich versuche, die SpringBoot Anwendung zu starten, erhalte ich folgende Fehlermeldung:

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 

Antwort

0

Die beste Lösung, die ich finden kann, ist, die Dinge so restrukturieren, dass die „NodeEntity“ a „RelationshipEntity“ Klasse verwendet, und die RelationshipEntity Klasse verwendet eine "RelationshipType" -Klasse, und die RelationshipType-Klasse enthält die gemeinsamen Attribute. Beispiel:

@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(); 
    } 
} 

Dann in Ausführung ich etwas wie folgt aus:

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); 

Das ist für mich arbeitet, und scheint der beste Weg zu sein, die ich finden kann.

Verwandte Themen