3
votes

We have an orientdb with vertices and light-weight edges. Now there are 2 vertices that should have an edge in between them. However, the edge seems to be outgoing from one side, but not incoming from the other. I thought OrientDb edges were always traversable in both directions.

Screenshot of web interface

As you can see, 15:3 has an out-edge to 17:1, but 17:1 does not have a corresponding in-edge.

What's going on here? Is this a bug or is this actually an acceptable situation in OrientDb?

FYI this is a developers database. Nobody is accessing the db in between the two queries from the screenshot. The problem is hard to reproduce because it doesn't always occur.

EDIT: extra information

Using OrientDb 2.1.9. Edges are created using the tinkerpop API. We do use transactions (although this problem doesn't necessarily occur after a single transaction. Again, the problem is hard to isolate and replicate).

1
Have you done some delete operations before ?Alessandro Rota
Nope, we don't do any deletions at allDavid ten Hove
I need a couple more info: 1) OrientDB version you are using. 2) How are you doing the vertex/edge creation (which API)? 3) Are you using transactions?Luigi Dell'Aquila
Thanks @DavidtenHove if you always use transactions these inconsistencies should never happen, so I'd say it's a bug. I suggest you to upgrade to latest 2.1 stable (2.1.19 at the time I'm writing) or even better to 2.2, there are no open issues about that currentlyLuigi Dell'Aquila
@LuigiD thank you for your clarifications. Unfortunately, switching to a newer version of OrientDb isn't so easy right now.David ten Hove

1 Answers

0
votes

So apparently this happens when you do the following:

        OrientGraph tx = factory.getTx();
        Vertex vertex1 = createVertex(tx);
        Vertex vertex2 = createVertex(tx);
        Supplier<Vertex> getTargetVertex = () -> {
            Iterable<Vertex> vertices = tx.command(new OCommandSQL("select from " + targetRid).execute();
            return vertices.iterator().next();
        };
        vertex1.addEdge(ClassNames.REFERENCE, getTargetVertex.get());
        vertex2.addEdge(ClassNames.REFERENCE, getTargetVertex.get());
        tx.commit();

Let's say the target vertex in the database has version 1. In this example, the vertex is fetched twice and two edges are placed to that vertex. This makes it so that there will be two target vertices with version 2. When committing, OrientDb picks one (looks like always the first) and commits that target vertex.

The solution is to only fetch the target vertex once for each transaction.

It would have been mighty nice for OrientDb to throw an exception or something like that though...