I'm receiving the following error while using the @GremlinGroovy annotation associated with tinkerpop's frames.
java.lang.ClassCastException: com.thinkaurelius.titan.graphdb.relations.CacheEdge cannot be cast to com.tinkerpop.blueprints.Vertex
at com.tinkerpop.frames.structures.FramedVertexIterable$1.next(FramedVertexIterable.java:36)
at com.tinkerpop.frames.annotations.gremlin.GremlinGroovyAnnotationHandler.processVertex(GremlinGroovyAnnotationHandler.java:75)
at com.tinkerpop.frames.annotations.gremlin.GremlinGroovyAnnotationHandler.processElement(GremlinGroovyAnnotationHandler.java:114)
at com.tinkerpop.frames.annotations.gremlin.GremlinGroovyAnnotationHandler.processElement(GremlinGroovyAnnotationHandler.java:30)
at com.tinkerpop.frames.FramedElement.invoke(FramedElement.java:83)
at com.sun.proxy.$Proxy81.getProxyCandidateEdgeFromPersonUuid(Unknown Source)
at com.company.prod.domain.Person$Impl.toImpl(Person.java:100)
....
The following line causes the error:
FooEdge fe = foo.getFooEdgeFromUuid(this.getUuid());
Which is calling this method:
@GremlinGroovy("it.outE('has').filter{it.inV().has('uuid', T.eq, uuid).hasNext()}")
FooEdge getFooEdgeFromUuid(@GremlinParam("uuid") String uuid);
I've also tried the following traversal (which causes the same error):
@GremlinGroovy("it.out('has').has('uuid', T.eq, uuid).inE('has')")
However, when I open a gremlin shell to test out the same exact traversal - everything works out just fine. Any thoughts on what may be causing the issue?
This isn't as much of an answer as it is to a workaround. Instead of using the @GremlinGroovy annotation one can use gremlin with the @JavaHandler annotation.
@JavaHandler
void getFooEdgeFromUuid(String uuid);
abstract class Impl implements JavaHandlerContext<Vertex>, Foo {
public FooEdge getFooEdgeFromUuid(String uuid) {
return frameEdges(
gremlin().out("has")
.has("person-uuid", Tokens.T.eq, uuid)
.inE("has"),
FooEdge.class).iterator().next();
}
}
I don't think you have proper usage there give the documentation on Frames for that annotation:
https://github.com/tinkerpop/frames/wiki/Gremlin-Groovy
First, note that both:
@GremlinGroovy("it.outE('has').filter{it.inV().has('uuid', T.eq, uuid).hasNext()}")
FooEdge getFooEdgeFromUuid(@GremlinParam("uuid") String uuid);
and:
@GremlinGroovy("it.out('has').has('uuid', T.eq, uuid).inE('has')")
returns an Iterator
so that's not so helpful either as you would need to return some form of List
in your getFooEdgeFromUuid()
. Perhaps the appropriate thing to do, assuming you know for a fact that this query will only and always return one edge would be to do:
@GremlinGroovy("it.out('has').has('uuid', T.eq, uuid).inE('has').next()")
I say "always" because without that, you'll get yourself a NoSuchElementException
otherwise. In that way, to align types properly, you could do:
@GremlinGroovy("it.outE('has').filter{it.inV().has('uuid', T.eq, uuid)}")
Iterable<FooEdge> getFooEdgesFromUuid(@GremlinParam("uuid") String uuid);
Of course, all that may not work, because of this sentence I see in the docs:
It is possible to make use of a Gremlin path expression as a means of determining vertex adjacency via the GremlinGroovyModule.
In other words, use of @GremlinGroovy
is for returning framed vertices (and not edges as you are trying to do). If the approach I suggested above doesn't work then your workaround using the @JavaHandler
may be your best option.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.