使用 org.apache.tinkerpop:tinkergraph-gremlin:3.7.0 时,以下语句有效。它包含 3 个合并语句。用简单的英语来说:插入顶点端点 e1,更新插入顶点权限 p1,更新插入来自 e1->p1 的 REQUIRES_PERMISSION 边。
TinkerGraph.open().traversal()
.mergeV(Map.of(
T.id, "e1",
T.label, "endpoint"))
.as("e")
.mergeV(Map.of(
T.id, "p1",
T.label, "permission"))
.option(Merge.onCreate, Map.of("value", "read-only"))
.as("p")
.mergeE(Map.of(
T.label, "REQUIRES_PERMISSION",
Direction.from, Merge.outV,
Direction.to, Merge.inV
))
.option(Merge.outV, select("e"))
.option(Merge.inV, select("p"))
.iterate();
但是,当我降级到 org.apache.tinkerpop:tinkergraph-gremlin:3.6.2 时,相同的语句会引发异常。这是堆栈跟踪。
java.lang.UnsupportedOperationException
at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:72)
at java.base/java.util.ImmutableCollections$AbstractImmutableMap.putAll(ImmutableCollections.java:732)
at org.apache.tinkerpop.gremlin.process.traversal.step.map.MergeVertexStep.onCreateMap(MergeVertexStep.java:205)
at org.apache.tinkerpop.gremlin.process.traversal.step.map.MergeVertexStep.flatMap(MergeVertexStep.java:168)
at org.apache.tinkerpop.gremlin.process.traversal.step.map.FlatMapStep.processNextStart(FlatMapStep.java:49)
at org.apache.tinkerpop.gremlin.process.traversal.step.map.MergeStep.processNextStart(MergeStep.java:165)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:150)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.ExpandableStepIterator.next(ExpandableStepIterator.java:55)
at org.apache.tinkerpop.gremlin.process.traversal.step.map.FlatMapStep.processNextStart(FlatMapStep.java:48)
at org.apache.tinkerpop.gremlin.process.traversal.step.map.MergeStep.processNextStart(MergeStep.java:165)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.hasNext(AbstractStep.java:150)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.ExpandableStepIterator.next(ExpandableStepIterator.java:55)
at org.apache.tinkerpop.gremlin.process.traversal.step.filter.FilterStep.processNextStart(FilterStep.java:40)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:135)
at org.apache.tinkerpop.gremlin.process.traversal.step.util.AbstractStep.next(AbstractStep.java:40)
at org.apache.tinkerpop.gremlin.process.traversal.Traversal.iterate(Traversal.java:210)
at org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal.iterate(GraphTraversal.java:3331)
at org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal$Admin.iterate(GraphTraversal.java:202)
at org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal.iterate(DefaultGraphTraversal.java:48)
什么可以解释行为的差异,以及如何修正我的陈述以达到预期的结果?
我实际上已经找到了一个更简单的重现示例:
g.mergeV(Map.of(T.id, 300))
.option(Merge.onCreate, Map.of(T.label, "Dog", "name", "Toby", "age", 10))
.option(Merge.onMatch, Map.of("age", 11))
.next();
我已尽我所能将其从 Groovy 翻译为 Java,请参阅 https://tinkerpop.apache.org/docs/3.6.2/reference/#mergevertex-step,问题已经存在。
我想我已经找到了不同之处。
如果我们采用以下示例,
Map.of(T.id, 300)
可以是不可变的,但传递给 option() 方法的映射必须是可变的。 Map.of("age", 11)
是不可变的,这会导致 3.6.2 中出现 UnsupportedOperationException。然而,在 3.7.0 中,情况不再如此。在 3.7.0 中,接受不可变的映射。
g.mergeV(Map.of(T.id, 300))
.option(Merge.onCreate, Map.of(T.label, "Dog", "name", "Toby", "age", 10))
.option(Merge.onMatch, Map.of("age", 11))
.next();