2012-05-26 25 views
6

Korzystając z danych sprężynowych-neo4j, chcę utworzyć dwie klasy przy użyciu @RelationshipEntity(type="OWNS"), aby połączyć klasę Person z Pet i Car.Wiele klas relacji z tym samym typem

@RelationshipEntity(type="OWNS") 
public class OwnsCar { 
    @Indexed 
    private String name; 

    @StartNode 
    private Person person; 

    @EndNode 
    private Car car; 
} 

@RelationshipEntity(type="OWNS") 
public class OwnsPet { 
    @Indexed 
    private String name; 

    @EndNode 
    private Person person; 

    @StartNode 
    private Pet pet; 
} 

Oszczędza do Bazy Graph prawidłowo bez żadnych problemów, jak mogę zapytania rzeczywistą Node i Relationship i widzą typ itd

Ale gdy próbuję użyć @RelatedTo(type="OWNS", elementClass=Pet.class) I albo dostać wyjątek rzutu klasowego lub podczas używania leniwej inicjalizacji otrzymuję niepoprawne wyniki.

@NodeEntity 
public class Person { 
    @Indexed 
    private String name; 

    @RelatedTo(type="OWNS", direction=Direction.OUTGOING, elementClass=Pet.class) 
    private Set<Pet> pets; 

    @RelatedTo(type="OWNS", direction=Direction.OUTGOING, elementClass=Car.class) 
    private Set<Car> cars; 
} 

Wynik otrzymuję gdy próbuję wydrukować naszą moją osobę (mój toString() został pominięty, ale to po prostu wywołuje toString() dla każdego pola) jest taka:

Person [nodeId=1, name=Nick, pets=[Car [nodeId=3, name=Thunderbird]], cars=[Car [nodeId=3, name=Thunderbird]]] 

Czy ktoś wie, czy to można zrobić, należy zrobić, to tylko błąd lub funkcja, której brakuje?

Odpowiedz

3

Wygląda na to, że problem polega na tym, że adnotacja powoduje, że springDataNeo4j nadaje priorytet nazwie związku. Próbowałem tego samego na innej próbce, którą stworzyłem. Jeśli obie adnotacje zawierają type="OWNS", łączy on oba "obiekty". Kiedy pomijam tę informację i używam tylko kierunku i typu, działa to dla mnie.

Niestety spowoduje to problem, jeśli używasz innej @RelatedTo adnotacji z większą liczbą zwierząt lub samochodów związanych z inną adnotacją. Ponieważ nie różni się on pomiędzy "OWNS" i jakimkolwiek innym powiązaniem z typem zwierzęcia, zestaw zwraca wszystkie spokrewnione zwierzęta (przykład: peter -> (HATES-Relationsip) -> psy).

Jeśli to błąd, czy nie, nie mogę powiedzieć ... Ale dla bazy danych: Są tylko węzły i relacje. Oba nie są wpisane, więc neo4j nie wie nic o twojej klasie "Pet" lub "Car". Dane źródłowe neo4j obsługuje to, indeksując wszystkie węzły na typ i ustawiając atrybut typu lub używając określonego układu graficznego (z subreferencjami). Nawet jeśli chciałbyś pobrać wszystkie zwierzęta osoby z opisem trajektorii, miałbyś o wiele więcej kodu do napisania, ponieważ wychodzące relacje z nazwą "OWNS" zawierają dwa typy obiektów.

Polecam, używając dwóch różnych nazw. Łatwiej jest później pisać niestandardowe traversals/queries, a także prawdopodobnie jeszcze szybciej, ponieważ nie będzie potrzebne żadne porównanie typu klasowego. Czy jest jakikolwiek powód, dlaczego potrzebujesz tych konkretnych nazw?

PS: Możliwe, że nie wszystko jest w 100% dokładne. Nie znam szczegółowo springdataneo4j, ale to właśnie do tej pory wymyśliłem.