orientechnologies / orientdb

OrientDB is the most versatile DBMS supporting Graph, Document, Reactive, Full-Text and Geospatial models in one Multi-Model product. OrientDB can run distributed (Multi-Master), supports SQL, ACID Transactions, Full-Text indexing and Reactive Queries.
https://orientdb.dev
Apache License 2.0
4.75k stars 871 forks source link

IllegalMonitorStateException #2113

Closed andrii0lomakin closed 10 years ago

andrii0lomakin commented 10 years ago

Please find attached the test case. There won't be any error in the first run of the program. The error shows from the second run onwards when the edge is added and committed. If the line 'graph.createKeyIndex(keyName, Vertex.class, new Parameter("class", className));' is commented it will work fine.

Regards Gino

import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future;

import com.orientechnologies.orient.core.metadata.schema.OClass; import com.tinkerpop.blueprints.Parameter; import com.tinkerpop.blueprints.Vertex; import com.tinkerpop.blueprints.impls.orient.OrientBaseGraph; import com.tinkerpop.blueprints.impls.orient.OrientEdge; import com.tinkerpop.blueprints.impls.orient.OrientGraph; import com.tinkerpop.blueprints.impls.orient.OrientVertex;

public final class OrientDBLockExceptionTest {

private static String className = "Employee";
private static String keyName = "fName";

public void runTest() {
    OrientBaseGraph graph = new OrientGraph("plocal:/tmp/testdb");
    OClass clazz = graph.getVertexType(className);
    if (clazz == null) {
        graph.createVertexType(className);
        graph.createEdgeType("Connected");
    }
    graph.createKeyIndex(keyName, Vertex.class, new Parameter("class", className));
    Set<String> keys = graph.getIndexedKeys(Vertex.class, true);
    System.out.println("Keys = " + keys);
    graph.shutdown();

    List<Future<Void>> futureList = new ArrayList<>();
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    for (int i = 0; i < 2; i++) {
        Future<Void> future = executorService.submit(new WorkerThread(i));
        futureList.add(future);
    }
    for (Future<Void> f : futureList) {
        try {
            f.get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    graph = new OrientGraph("plocal:/tmp/testdb");
    System.out.println("Adding links");
    for (int i = 0; i < 9; i++) {

        Iterable<Vertex> srcNodes = graph.getVertices("Employee.fName", "name-0-" + i);
        Iterable<Vertex> srcNodes1 = graph.getVertices("Employee.fName", "name-1-" + i);
        for (Vertex source : srcNodes) {
            for (Vertex destination : srcNodes1) {
                System.out.println("*********** Adding edges....");
                OrientEdge edge = (OrientEdge) ((OrientVertex)source).addEdge("Connected", destination);
                edge.setProperty("test", "test");
                graph.commit();
            }
        }
    }
    graph.shutdown();

    executorService.shutdown();
    System.out.println("Processing done");
}

public static void main(String[] args) {
    OrientDBLockExceptionTest test = new OrientDBLockExceptionTest();
    test.runTest();
}

public static class WorkerThread implements Callable<Void> {

    private int count;

    public WorkerThread(int count) {
        this.count = count;
    }

    @Override
    public Void call() throws Exception {
        OrientBaseGraph graph = new OrientGraph("plocal:/tmp/testdb");
        for (int i = 0; i < 11; i++) {
            Vertex vtx = graph.addVertex("class:"+className);
            vtx.setProperty(keyName, "name-" + this.count + "-" + i);
            vtx.setProperty("lname", "lname" + i);
            graph.commit();
        }
        graph.shutdown();
        System.out.println("Thread done");
        return null;
    }
}

}

andrii0lomakin commented 10 years ago

I have changed code a bit, everything works fine now. Look at my gist - https://gist.github.com/laa/ddd7352b17f8e39c22d6 . Do not recreate indexes at runtime.

valenpo commented 10 years ago

Not really same

All indexes and classes I created when DB started, but edge has no any indexes: Also each edge is newly created, so it is not update the property.

Simple test behavior is like you traverse folder with subfolders where file and folder are vertexes and if edges are connection's between them like test_folder(v_folder) --e(folder)--> test_file.txt(v_file)

for (ItemType type : ItemType.values()) { try { OrientVertexType ovt = graph.createVertexType(type.getClassName());

            try {
                List<IndexedProperty> indexedProperties = getBasicItem(type).getIndexedProperties();

                for (IndexedProperty indexProperty : indexedProperties) {
                    String indexName = indexProperty.name();
                    ovt.createProperty(indexName, OType.STRING);
                    ovt.createIndex(indexName, INDEX_TYPE.UNIQUE, indexProperty.name());
                }

            } catch (DatabaseException e) {
                logger.debug("failed get basic item from type {"+type.toString()+"} :"+e.getMessage());
            } 

        } catch (OSchemaException e) {
            logger.debug("Vertex class "+type.toString()+" already exists in current database", e);
        }
    };

    for (Relationship relation : Relationship.values()) {
        try {
            OrientEdgeType oet =  graph.createEdgeType(relation.getClassName());
        } catch (OSchemaException e) {
            logger.debug("Edge class "+relation.toString()+" already exists in current database", e);
        }
    };

where

public enum ItemType {
    ROOT, USER, FOLDER, BLOB, TAG, PROPERTY;

    public String getClassName() {
        return "v_"+ super.toString().toLowerCase(Locale.ENGLISH);  
    }

    public String getObjectClassNameId() {
        return "class:"+ getClassName();
    }

    public static boolean containsClass(String className) {
        className = className.substring(2).toUpperCase(Locale.ENGLISH);
        return ItemType.valueOf(className)!=null;
    }

    public static ItemType getType(String className) {
        className = className.substring(2).toUpperCase(Locale.ENGLISH);
        return ItemType.valueOf(className);
    }

};

public enum Relationship {
    USER, TAGS, PROPERTIES,
    FOLDERVERSION, ITEMVERSION, //used for versioned relations 
    FOLDER, ITEM, // used to store tree structure
    THREAD,
    KNOW;

    public String getClassName() {
        return "e_"+ super.toString().toLowerCase(Locale.ENGLISH);  
    }

    public String getObjectClassNameId() {
        return "class:"+ getClassName();
    }

    @Override
    public String toString() {
        return super.toString().toLowerCase(Locale.ENGLISH);
    }

};
andrii0lomakin commented 10 years ago

Hi, Do you always call ovt.createIndex(indexName, INDEX_TYPE.UNIQUE, indexProperty.name()) during this test execution ?

On Mon, Mar 17, 2014 at 10:09 AM, valenpo notifications@github.com wrote:

Not really same

All indexes and classes I created when DB started, but edge has no any indexes: Also each edge is newly created, so it is not update the property.

Simple test behavior is like you traverse folder with subfolders where file and folder are vertexes and if edges are connection's between them like test_folder(v_folder) --e(folder)--> test_file.txt(v_file)

for (ItemType type : ItemType.values()) { try { OrientVertexType ovt = graph.createVertexType(type.getClassName());

        try {
            List<IndexedProperty> indexedProperties = getBasicItem(type).getIndexedProperties();

            for (IndexedProperty indexProperty : indexedProperties) {
                String indexName = indexProperty.name();
                ovt.createProperty(indexName, OType.STRING);
                ovt.createIndex(indexName, INDEX_TYPE.UNIQUE, indexProperty.name());
            }

        } catch (DatabaseException e) {
            logger.debug("failed get basic item from type {"+type.toString()+"} :"+e.getMessage());
        }

    } catch (OSchemaException e) {
        logger.debug("Vertex class "+type.toString()+" already exists in current database", e);
    }
};

for (Relationship relation : Relationship.values()) {
    try {
        OrientEdgeType oet =  graph.createEdgeType(relation.getClassName());
    } catch (OSchemaException e) {
        logger.debug("Edge class "+relation.toString()+" already exists in current database", e);
    }
};

where

public enum ItemType { ROOT, USER, FOLDER, BLOB, TAG, PROPERTY;

public String getClassName() {
    return "v_"+ super.toString().toLowerCase(Locale.ENGLISH);
}

public String getObjectClassNameId() {
    return "class:"+ getClassName();
}

public static boolean containsClass(String className) {
    className = className.substring(2).toUpperCase(Locale.ENGLISH);
    return ItemType.valueOf(className)!=null;
}

public static ItemType getType(String className) {
    className = className.substring(2).toUpperCase(Locale.ENGLISH);
    return ItemType.valueOf(className);
}

};

public enum Relationship { USER, TAGS, PROPERTIES, FOLDERVERSION, ITEMVERSION, //used for versioned relations FOLDER, ITEM, // used to store tree structure THREAD, KNOW;

public String getClassName() {
    return "e_"+ super.toString().toLowerCase(Locale.ENGLISH);
}

public String getObjectClassNameId() {
    return "class:"+ getClassName();
}

@Override
public String toString() {
    return super.toString().toLowerCase(Locale.ENGLISH);
}

};

— Reply to this email directly or view it on GitHubhttps://github.com/orientechnologies/orientdb/issues/2113#issuecomment-37792366 .

Best regards, Andrey Lomakin.

Orient Technologies the Company behind OrientDB

valenpo commented 10 years ago

No, it is called only 1st time with fresh DB. Afterwards when you call OrientVertexType ovt = graph.createVertexType(type.getClassName()); it throw OSchemaException exception, so this code doesn't called 2nd time.

In any case I have same issue with fresh DB. (when index creation called on 1st and last time).

Also as I sad before, I could insert 1 edge.

Regards Valentin

andrii0lomakin commented 10 years ago

Ok. Then is it possible for me to reproduce it ? Do you have test case ?

On Mon, Mar 17, 2014 at 10:49 AM, valenpo notifications@github.com wrote:

No, it is called only 1st time with fresh DB. Afterwards when you call OrientVertexType ovt = graph.createVertexType(type.getClassName()); it throw OSchemaException exception, so this code doesn't called 2nd time.

In any case I have same issue with fresh DB. (when index creation called on 1st and last time)

Regards Valentin

— Reply to this email directly or view it on GitHubhttps://github.com/orientechnologies/orientdb/issues/2113#issuecomment-37794528 .

Best regards, Andrey Lomakin.

Orient Technologies the Company behind OrientDB

valenpo commented 10 years ago

Andrey, I could provide you access to testing environment with eclipse and everything else. Writing test cases could take time, as it has some logic. The main goal is to import pst file and store all structure of folders.