Neo4j graph.index (). ForNodes cannot find nodes

I am trying to create unique TEST nodes with a unique id property.

However, the forNodes () method does not detect duplicates, is there a better method using only the Java API and why does the following not work?

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

The above:

 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] 

shouldn't the above be detected when i = 1, that node already exists with id = 99 ???

EDIT : The same error also in different transactions.

 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
source share
1 answer

The real problem that you discover is that testIterator returns false when it should return true. When I == 1, the iterator should have returned! True, because it already has one further insert.

But it does not work the way it was designed, then it proceeds to insert, and you get an exception, as it should be. The count recognizes a violation of uniqueness.

What you do not know is that the iterator is cached without updating after the transaction.

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

Please note that switching from 0 to 1 nodes does NOT include any uniqueness. Here the iterator fails: not updated

0
source

Source: https://habr.com/ru/post/917901/


All Articles