我尝试使用" id"的唯一属性创建TEST类型的唯一节点。
然而,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();
}
}
}
}
}
以上回报:
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]
当i = 1时,上面的检测不应该已经是id = 99的节点???
编辑:同样的错误也出现在不同的交易中..
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 :(得分:0)
您发现的真正问题是testIterator在返回true时返回false。当i == 1时,迭代器应该返回!是因为它已经有一个没有进一步插入应该发生。
但它没有按照设计工作,然后继续插入,你得到一个应该是的例外。该图表识别出唯一性违规。
您不知道的是,在提交事务后是否正在缓存迭代器而不进行更新
if (!testIterator.hasNext())
{
...
}
请注意,从0到1节点不涉及任何唯一性。这是迭代器失败的地方:没有更新