2017-02-15 11 views
0

"id"の一意のプロパティを持つTEST型の一意のノードを作成しようとしています。Neo4j graph.index()。ノードが見つからないノード

forNodes()メソッドは重複を検出していませんが、Java APIのみを使用するより良い方法がありますか?

public class Neo4jTest 
{ 
    public static void main(String args[]) 
    { 
     GraphDatabaseService graph = new TestGraphDatabaseFactory().newImpermanentDatabase(); 

     Label testLabel = new Label() 
     { 
      @Override 
      public String name() 
      { 
       return "TEST"; 
      } 
     }; 

     try (Transaction tx = graph.beginTx()) 
     { 
      graph.schema() 
        .constraintFor(testLabel) 
        .assertPropertyIsUnique("id") 
        .create(); 
      tx.success(); 
     } 

     try (Transaction tx = graph.beginTx()) 
     { 
      int k = 99; 
      for (int i = 0; i < 4; i++) 
      { 
       System.out.println("indexing... i="+i); 
       Index<Node> testIndex = graph.index().forNodes(testLabel.name()); 
       IndexHits<Node> testIterator = testIndex.get("id", k); 

       if (!testIterator.hasNext()) 
       { 
        System.out.println("creating node... i="+i); 
        Node testNode = graph.createNode(testLabel); 
        testNode.setProperty("id", k); 
        tx.success(); 
       } 
      } 
     } 
    } 
} 

上記戻り値:i = 1のとき

indexing... i=0 
creating node... i=0 
indexing... i=1 
creating node... i=1 
Exception in thread "main" org.neo4j.graphdb.ConstraintViolationException: Node 0 already exists with label TEST and property "id"=[99] 

は、上記のIDを持つノード= 99が既にがあることを検出してはなりません?

EDIT:別のトランザクションでも同じエラー..

public class Neo4jTest 
{ 

    public static void main(String args[]) 
    { 
     GraphDatabaseService graph = new TestGraphDatabaseFactory().newImpermanentDatabase(); 

     Label testLabel = new Label() 
     { 
      @Override 
      public String name() 
      { 
       return "TEST"; 
      } 
     }; 

     try (Transaction tx = graph.beginTx()) 
     { 
      graph.schema() 
        .constraintFor(testLabel) 
        .assertPropertyIsUnique("id") 
        .create(); 
      tx.success(); 
     } 

     int k = 99; 

     try (Transaction tx = graph.beginTx()) 
     { 
      System.out.println("indexing... i=" + 0); 
      Index<Node> testIndex = graph.index().forNodes(testLabel.name()); 
      IndexHits<Node> testIterator = testIndex.get("id", k); 

      if (!testIterator.hasNext()) 
      { 
       System.out.println("creating node... i=" + 0); 
       Node testNode = graph.createNode(testLabel); 
       testNode.setProperty("id", k); 

      } 
      tx.success(); 
     } 

     try (Transaction tx = graph.beginTx()) 
     { 
      System.out.println("indexing... i=" + 1); 
      Index<Node> testIndex = graph.index().forNodes(testLabel.name()); 
      IndexHits<Node> testIterator = testIndex.get("id", k); 

      if (!testIterator.hasNext()) 
      { 
       System.out.println("creating node... i=" + 1); 
       Node testNode = graph.createNode(testLabel); 
       testNode.setProperty("id", k); 
      } 
      tx.success(); 
     } 
    } 
} 

答えて

0

あなたが探している本当の問題は、それがtrueを返すときtestIteratorがfalseを返すされていることです。 i == 1のとき、iteratorはすでにそれ以上の挿入が起こってはならないので、trueを返していたはずです。

しかし、設計どおりに動作していないため、挿入が進み、例外が発生する可能性があります。グラフは一意性違反を認識しています。イテレータはトランザクションが0〜1のノードから行くこと任意の一意性を必要としないことを

if (!testIterator.hasNext()) 
{ 
... 
} 

お知らせをコミットされた後、更新せずにキャッシュされているかどうかわからない何

です。これはイテレータが失敗している場所です:更新されていません

+0

!testIterator.hasNext()は例外がスローされる前に2回発生し、出力を参照すると、txはi> = 0、実際には!testIterator.hasNext()常に失敗しますが、なぜですか? –

+0

これは新しい情報です。しかし、コードを見ると、挿入はif(!iterator.hasNext())の内部でのみ起こりますので、i == 0のときに一度だけ起こるようです。その後、次のイテレータはhaveNext )== true。単純化してループを取り除き、挿入、コミット、再度挿入する場合は、例外 – efekctive

+0

を使用して、全体の答えとコメントを言い換えることができますか?もしそれがNeoのバグであれば、そうしてください、挿入を行うコードを投稿しないと例外なくしたいです。 –

関連する問題