Gremlin Groovy ClassCastException с фреймами

Я получаю следующую ошибку при использовании аннотации @GremlinGroovy, связанной с фреймами tinkerpop.

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)
    ....

Следующая строка вызывает ошибку:

FooEdge fe = foo.getFooEdgeFromUuid(this.getUuid());

Который вызывает этот метод:

@GremlinGroovy("it.outE('has').filter{it.inV().has('uuid', T.eq, uuid).hasNext()}")
FooEdge getFooEdgeFromUuid(@GremlinParam("uuid") String uuid);

Я также пробовал следующий обход (который вызывает ту же ошибку):

@GremlinGroovy("it.out('has').has('uuid', T.eq, uuid).inE('has')")

Однако, когда я открываю оболочку gremlin для проверки того же самого обхода - все работает просто отлично. Есть мысли о том, что может быть причиной проблемы?

2 ответа

Это не столько ответ, сколько обходной путь. Вместо использования аннотации @GremlinGroovy можно использовать gremlin с аннотацией @JavaHandler.

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

Я не думаю, что у вас есть правильное использование там дать документацию на кадры для этой аннотации:

https://github.com/tinkerpop/frames/wiki/Gremlin-Groovy

Во-первых, обратите внимание, что оба:

@GremlinGroovy("it.outE('has').filter{it.inV().has('uuid', T.eq, uuid).hasNext()}")
FooEdge getFooEdgeFromUuid(@GremlinParam("uuid") String uuid);

а также:

@GremlinGroovy("it.out('has').has('uuid', T.eq, uuid).inE('has')")

возвращает Iterator так что это не так полезно, так как вам нужно будет вернуть некоторую форму List в вашем getFooEdgeFromUuid(), Возможно, это будет уместно, если вы точно знаете, что этот запрос будет только и всегда возвращать одно ребро:

@GremlinGroovy("it.out('has').has('uuid', T.eq, uuid).inE('has').next()")

Я говорю "всегда", потому что без этого вы получите себе NoSuchElementException иначе. Таким образом, чтобы правильно выровнять типы, вы можете сделать:

@GremlinGroovy("it.outE('has').filter{it.inV().has('uuid', T.eq, uuid)}")
Iterable<FooEdge> getFooEdgesFromUuid(@GremlinParam("uuid") String uuid);

Конечно, все, что не может работать, из-за этого предложения я вижу в документах:

Можно использовать выражение пути Gremlin в качестве средства определения смежности вершин с помощью модуля GremlinGroovyModule.

Другими словами, использование @GremlinGroovy предназначен для возврата подставленных вершин (а не ребер, как вы пытаетесь это сделать). Если подход, который я предложил выше, не работает, то ваш обходной путь, используя @JavaHandler может быть ваш лучший вариант.

Другие вопросы по тегам