2016-07-05 10 views
0

私はSpring Data Neo4j 4を使用しています。 はジョージとジョン・KNOWS->同じタイプのノードをSDNと関連付ける

@NodeEntity 
public class Person { 

    @GraphId private Long id; 

    private String name; 

    private String lastName; 

    @Relationship(type = "KNOWS") 
    Set<Person> myTypes; 


} 

であると私は `

ジョン・KNOWS-のようなグラフを作成しようとしています、私はPerson型のノードと、対応するJavaドメインオブジェクトを考えてみましょう> Ann。 Ann-KNOWS-> Dug

`。以下は、私がどのようにドメインオブジェクトを設定し、永続化しているかです。

Person john = new Person("John","P"); 
    Person george = new Person("George","B"); 
    Person Ann = new Person("Ann","M"); 
    Person Dug = new Person("Dug","S"); 
    Set<Person> Persons= new HashSet<Person>(); 
    Set<Person> Persons1= new HashSet<Person>(); 
    Persons1.add(Dug); 
    Ann.setMyTypes(Persons1); 
    Persons.add(george); 
    Persons.add(Ann); 
    john.setMyTypes(Persons); 

    personRepository.save(john); 
    personRepository.save(george); 
    personRepository.save(Ann); 
    personRepository.save(Dug); 

しかし、驚いたことにノードは関係なく作成されます。私はこれをデバッグしていましたが、この行の後に personRepository.save(john) 関係のあるノードが作成されましたが、その後の保存中にすべての関係が削除されました。 以下はログに表示されるもので、関係が削除されていることを明確に示しています。

Request: UNWIND {rows} as row CREATE (n:`Person`) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, row.type as type with params {rows=[{nodeRef=-2115049587, type=node, props={name=George, attrib=B}}, {nodeRef=-341599918, type=node, props={name=Ann, attrib=M}}, {nodeRef=-737678933, type=node, props={name=John, attrib=P}}, {nodeRef=-1025122203, type=node, props={name=Dug, attrib=S}}]} 
Request: UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId MATCH (endNode) WHERE ID(endNode) = row.endNodeId MERGE (startNode)-[rel:`KNOWS`]->(endNode) RETURN row.relRef as ref, ID(rel) as id, row.type as type with params {rows=[{relRef=-1807300324, endNodeId=2448, type=rel, startNodeId=2450}, {relRef=-272508006, endNodeId=2451, type=rel, startNodeId=2449}, {relRef=-845107952, endNodeId=2449, type=rel, startNodeId=2450}]} 
Request: UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId MATCH (endNode) WHERE ID(endNode) = row.endNodeId MATCH (startNode)-[rel:`KNOWS`]->(endNode) DELETE rel with params {rows=[{endNodeId=2448, startNodeId=2450}]} 
Request: UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId MATCH (endNode) WHERE ID(endNode) = row.endNodeId MATCH (startNode)-[rel:`KNOWS`]->(endNode) DELETE rel with params {rows=[{endNodeId=2449, startNodeId=2450}]} 
Request: UNWIND {rows} as row MATCH (startNode) WHERE ID(startNode) = row.startNodeId MATCH (endNode) WHERE ID(endNode) = row.endNodeId MATCH (startNode)-[rel:`KNOWS`]->(endNode) DELETE rel with params {rows=[{endNodeId=2451, startNodeId=2449}]} 

わからないがどこが間違っているつもりですかこれは、私は問題はあなたがPersonオブジェクトを保存している方法であると思い

答えて

0

を動作するようになっている方法です。 解決策の1つは、人物オブジェクトを先に保存することです。その後、関係を追加し、追加されたエンティティではなく、関係を追加したエンティティのみを再保存します。例

Person john = new Person("John","P"); 
    Person Ann = new Person("Ann","M"); 

    Set<Person> Persons= new HashSet<Person>(); 
    Persons.add(Ann); 
    john.setMyTypes(Persons); 
    personRepository.save(john); 

については

上記は、ジョンとアンの両方を節約するだけでなく、それらの間の「認識」の関係を作成します。 Annをもう一度保存する必要はありません。 Neo4jの時にアン関係がなかったとして任意の関係を持っていないエンティティとしてそれを見るように上記のコード

personRepository.save(Ann); 

後の関係が削除されます

再度アンを保存しようとすると、オブジェクトが以前に作成された

2

これは、OGMが同じタイプであるが特定の方向に存在するため、OGMの関係があいまいである場合です。

(john)-[:KNOWS]->(george)は、GeorgeがJohnからの着信関係を持つ必要があることを示していますが、ドメインモデルにはこれが反映されていません。その後の保存では、気付いたように、マッパーはあいまいさのために何を保存するのか把握できないため、関係が削除されます。

同じ種類のエンティティ間にこれらの種類の関係がある場合、関係方向を明示的に指定することが解決策です。 あなたの場合、ある人から他の人への関係は常に発信方向にあるため、このような方向を追加すると、OGMは同じタイプの着信関係について心配しないことが明らかです。

@Relationship(type = "KNOWS", direction = "OUTGOING") 
Set<Person> myTypes; 

はまた、あなたはOGMはジョンからジョージとアンに、従って掘っに行き来することができますので、ジョンが十分にある節約、あなたの例では、すべてのperson-を保存する必要はありません。

+0

ありがとうございました。しかし、上記は単純なユースケースです。私が何を目指しているのかは、巨大なExcelファイルからデータをインポートすることです。何を保存するのか把握しなければならないのか、それ自体は大きな課題になります。第二に、私は多くの場合、手の前に関係の方向性を知らない。実行時に方向を指定できる方法はありますか?投稿の下には表示されません http://stackoverflow.com/questions/18517000/dynamicrelationshiptype-in​​-spring-data-neo4j-or-defining-relationship-types-at-r –

+1

いいえ、実行時に経路を指定することはできませんSDN/OGMと一緒にOGMは仕事のための適切なツールではないかもしれません。つまり、Excelからのインポートです。 – Luanne

関連する問題