Search code examples
orientdborientdb3.0

OrientDB inconsistent vertex persist after remove edge with MMAPI


Consider this code:

private void testMMAPIinLab() {
    OrientDB orientDB = new OrientDB("remote:localhost",OrientDBConfig.defaultConfig());
    
    OrientDBConfigBuilder poolCfg = OrientDBConfig.builder();
    poolCfg.addConfig(OGlobalConfiguration.DB_POOL_MIN, 5);
    poolCfg.addConfig(OGlobalConfiguration.DB_POOL_MAX, 10);
    //poolCfg.addConfig(OGlobalConfiguration.RID_BAG_EMBEDDED_TO_SBTREEBONSAI_THRESHOLD, -1);
    ODatabasePool dbPool = new ODatabasePool(orientDB,"lab", "root", "toor", poolCfg.build());
    
    
    ODatabaseSession db = dbPool.acquire();

    db.begin();
    System.out.println("creando el vértice....");
    OVertex v1 = db.newVertex();
    v1.save();
    System.out.println("save rid: "+v1.getIdentity().toString());
    
    OVertex v2 = db.newVertex();
    v2.save();
    System.out.println("v2 save rid: "+v2.getIdentity().toString());

    System.out.println("crear un edge.");
    OEdge oe = v1.addEdge(v2);
    v1.save();
    
    System.out.println("llamando a commit...");
    db.commit();
    db.close();
    
    System.out.println("configuración grabada:");
    System.out.println("v1: "+v1.getIdentity().toString());
    System.out.println("v2: "+v2.getIdentity().toString());
    System.out.println("edge: "+oe.getFrom()+" --> "+oe.getTo());
    
    // abrir otra transacción
    db = dbPool.acquire();
    db.begin();
    System.out.println("crear v3");
    OVertex v3 = db.newVertex();
    v3.save();
    System.out.println("v3 save rid: "+v3.getIdentity().toString());
    
    System.out.println("modificar v1...");
    v1.setProperty("value", "test");
    
    System.out.println("borrar relación con v2");
    // borrar el edge anterior
    Iterator<OEdge> toRemove = v1.getEdges(ODirection.OUT).iterator();
    while (toRemove.hasNext()) {
        OEdge removeEdge = toRemove.next();
        //removeEdge = (OEdge) edge;
        removeEdge.delete();
        removeEdge.save();
    }
    
    System.out.println("agregar una relación de v1 a v3");
    OEdge oe2 = v1.addEdge(v3);
    
    v1.save();

    // crera en edge nuevo a v3
    db.commit();
    
    System.out.println("v1 edges: "+v1.getEdges(ODirection.OUT));
    System.out.println("v3 post-commit rid: "+v3.getIdentity().toString());
    System.out.println("oe2: "+oe2.getFrom()+" --> "+oe2.getTo());
    
    db.close();
    
}

When you run it you get V1 with two out edges. One with the EdgeRID of the removed edge and one that point to V3. I you clic over the removed edge it show {} and report a 404 error. The vertex are persisted so the error is inside the database.

The error is in the while that remove the edges. If you use the edge reference it work, but in the real code I do not know how many edges the vertex have.

V2 and V3 have the correct IN references.

How could I fix this?


Solution

  • This depends on the fact that vertices are shared between different database sessions.

    An easy fix consists in reloading the vertices by ID before using them in the second session:

    // abrir otra transacción
    db = dbPool.acquire();
    db.begin();
    
    //RELOAD THE VERTEX BEFORE USING IT AGAIN!
    v1 = db.load(v1.getIdentity());