Failing to save a new record in a in-memory database in distributed cluster

Hi All,
I’m trying a POC of OrientDB in a distributed mode - release 3.0.25.
I use the default configuration and run the nodes with docker-compose one by one.
after the first node is up, I log in to the studio, create a “in-memory” database and create a new class student with a property “grades” . and I try to save a new record I get this exception :

  • java.lang.ClassCastException: com.orientechnologies.orient.core.storage.memory.ODirectMemoryStorage cannot be cast to com.orientechnologies.orient.core.storage.disk.OLocalPaginatedStorage

what could be the problem?
```
here is the docker-compose I’m using:

version: ‘3.3’
services:
odb1:
image: orientdb:3.0.25
command: dserver.sh
volumes:
- ./var/odb1/config:/orientdb/config
- ./var/odb1/databases:/orientdb/databases
environment:
ORIENTDB_ROOT_PASSWORD: root
ORIENTDB_NODE_NAME: odb1
ports:
- 2480:2480
- 2424:2424

odb2:
image: orientdb:3.0.25
command: dserver.sh
volumes:
- ./var/odb2/config:/orientdb/config
- ./var/odb2/databases:/orientdb/databases
environment:
ORIENTDB_ROOT_USER: root
ORIENTDB_NODE_NAME: odb2
depends_on:
- odb1

odb3:
image: orientdb:3.0.25
command: dserver.sh
volumes:
- ./var/odb3/config:/orientdb/config
- ./var/odb3/databases:/orientdb/databases
environment:
ORIENTDB_ROOT_PASSWORD: root
ORIENTDB_NODE_NAME: odb3
depends_on:
- odb2

Hi @anatkabu

the memory storage is not supported in clustered environment. Probably that’s the issue

Thanks

Hi @wolf4ood,
Thanks for the quick response :slight_smile:
I have another question, is live query supported in clustered mode ?
I’m trying a simple piece of code using Java API against a remote cluster in a PLOCAL database, and getting NullPointerException. I’d be happy to give some more details about this issue, if it’s indeed supported.
thanks,
Anat.

Hi @anatkabu

it should be. Do you have the stacktrace of the exception?

Thanks

Hi, this is the stack trace:

Caused by: java.lang.NullPointerException
at com.orientechnologies.orient.server.distributed.impl.ODatabaseDocumentDistributed.copy(ODatabaseDocumentDistributed.java:179)
at com.orientechnologies.orient.core.sql.executor.LiveQueryListenerImpl$1.call(LiveQueryListenerImpl.java:76)
at com.orientechnologies.orient.core.sql.executor.LiveQueryListenerImpl.execInSeparateDatabase(LiveQueryListenerImpl.java:227)
at com.orientechnologies.orient.core.sql.executor.LiveQueryListenerImpl.(LiveQueryListenerImpl.java:73)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentEmbedded.live(ODatabaseDocumentEmbedded.java:686)
at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeSubscribeLiveQuery(OConnectionBinaryExecutor.java:1403)
at com.orientechnologies.orient.client.remote.message.OSubscribeLiveQueryRequest.execute(OSubscribeLiveQueryRequest.java:77)
at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeSubscribe(OConnectionBinaryExecutor.java:1331)
at com.orientechnologies.orient.client.remote.message.OSubscribeRequest.execute(OSubscribeRequest.java:78)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:310)
at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:212)
at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69)

Thanks @anatkabu

let me check

Hi @anatkabu

which users are you using for the connection? Server users or database users?

Thanks

Hi @wolf4ood,
I’m using the database user.
How can I know the server user ? (I understand it’s in the server xml - but it’s hashed)

I was able to reproduce it with server user like root but not with the default database user admin

I use this code to connect and open the database

 try (OrientDB dbClient = new OrientDB(dbUrl, "root", "root", OrientDBConfig.defaultConfig())) {
            dbClient.createIfNotExists(dbName, dbType);
            try (ODatabaseSession dbSession = dbClient.open(dbName, "root", "root")) {
                test.accept(dbSession);
            }
        } 

I use root - root ( in docker-compose I have ROOT_ORIENT_DB_PASSWORD = root
I don’t know what is the default admin password.
do you have an example of a sample code ?

@anatkabu

root is a server user. Try to use default database credentials admin - admin .

Probably it will solve the issue

I’m getting this exception with admin- admin:
com.orientechnologies.orient.core.exception.OSecurityAccessException: Wrong user/password to [connect] to the remote OrientDB Server instance

@anatkabu

use admin - admin only in the open API. Since it’s database user only works when operating against a database.

thank you @wolf4ood , I t tried it , now I get this exception in this line:
OClass oClass = session.createClass(“MyClass”);

com.orientechnologies.orient.server.distributed.ODistributedException: Error on creating cluster ‘myclass’ on distributed nodes: local and remote ids assigned are different

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.handleException(OChannelBinaryAsynchClient.java:338)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.handleStatus(OChannelBinaryAsynchClient.java:285)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.handleStatus(OChannelBinaryAsynchClient.java:307)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.beginResponse(OChannelBinaryAsynchClient.java:196)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.beginResponse(OChannelBinaryAsynchClient.java:158)
at com.orientechnologies.orient.client.remote.OStorageRemote.beginResponse(OStorageRemote.java:1888)
at com.orientechnologies.orient.client.remote.OStorageRemote.lambda$networkOperationRetryTimeout$2(OStorageRemote.java:245)
at com.orientechnologies.orient.client.remote.OStorageRemote.baseNetworkOperation(OStorageRemote.java:304)
at com.orientechnologies.orient.client.remote.OStorageRemote.networkOperationRetryTimeout(OStorageRemote.java:228)
at com.orientechnologies.orient.client.remote.OStorageRemote.networkOperationNoRetry(OStorageRemote.java:258)
at com.orientechnologies.orient.client.remote.OStorageRemote.command(OStorageRemote.java:944)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentRemote.command(ODatabaseDocumentRemote.java:407)
at com.orientechnologies.orient.core.metadata.schema.OSchemaRemote.createClass(OSchemaRemote.java:123)
at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:205)
at com.orientechnologies.orient.core.metadata.schema.OSchemaProxy.createClass(OSchemaProxy.java:93)
at com.orientechnologies.orient.core.db.ODatabase.createClass(ODatabase.java:558)
at com.slimgears.rxrepo.orientdb.OrientDbClientTest.lambda$insertWithAutoIncrement$11(OrientDbClientTest.java:190)
at com.slimgears.rxrepo.orientdb.OrientDbClientTest.rawDbTestWithParams(OrientDbClientTest.java:86)
at com.slimgears.rxrepo.orientdb.OrientDbClientTest.insertWithAutoIncrement(OrientDbClientTest.java:189)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Suppressed: com.orientechnologies.orient.server.distributed.ODistributedException: Error on creating cluster 'myclass' on distributed nodes: local and remote ids assigned are different
	at com.orientechnologies.orient.server.distributed.impl.ODistributedStorage.addCluster(ODistributedStorage.java:1248)
	at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.addCluster(ODatabaseDocumentAbstract.java:938)
	at com.orientechnologies.orient.core.metadata.schema.OSchemaEmbedded.createClusters(OSchemaEmbedded.java:370)
	at com.orientechnologies.orient.core.metadata.schema.OSchemaEmbedded.doCreateClass(OSchemaEmbedded.java:269)
	at com.orientechnologies.orient.core.metadata.schema.OSchemaEmbedded.createClass(OSchemaEmbedded.java:43)
	at com.orientechnologies.orient.core.metadata.schema.OSchemaShared.createClass(OSchemaShared.java:205)
	at com.orientechnologies.orient.core.metadata.schema.OSchemaProxy.createClass(OSchemaProxy.java:93)
	at com.orientechnologies.orient.core.sql.parser.OCreateClassStatement.executeDDL(OCreateClassStatement.java:81)
	at com.orientechnologies.orient.core.sql.executor.ODDLExecutionPlan.executeInternal(ODDLExecutionPlan.java:55)
	at com.orientechnologies.orient.core.sql.parser.ODDLStatement.execute(ODDLStatement.java:42)
	at com.orientechnologies.orient.core.sql.parser.OStatement.execute(OStatement.java:79)
	at com.orientechnologies.orient.core.db.document.ODatabaseDocumentEmbedded.command(ODatabaseDocumentEmbedded.java:567)
	at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeQuery(OConnectionBinaryExecutor.java:1188)
	at com.orientechnologies.orient.client.remote.message.OQueryRequest.execute(OQueryRequest.java:136)
	at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:310)
	at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:212)
	at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:69)

this is the code I’m trying to run

@Test
public void testLiveQuery() throws Exception {
    try (OrientDB dbClient = new OrientDB(dbUrl, "root", "root", OrientDBConfig.defaultConfig())) {
        dbClient.createIfNotExists("db2", ODatabaseType.PLOCAL);

        try (ODatabaseSession session = dbClient.open("db1", "admin", "admin")) {
            OClass oClass = session.createClass("MyClass");
            oClass.createProperty("num", OType.LONG);
            Observable<OElement> elements = Observable.create(emitter -> session.live("select from MyClass", new OLiveQueryResultListener() {
                @Override
                public void onCreate(ODatabaseDocument database, OResult data) {
                    emitter.onNext(data.toElement());
                }

                @Override
                public void onUpdate(ODatabaseDocument database, OResult before, OResult after) {
                }

                @Override
                public void onDelete(ODatabaseDocument database, OResult data) {

                }

                @Override
                public void onError(ODatabaseDocument database, OException exception) {
                    emitter.onError(exception);
                }

                @Override
                public void onEnd(ODatabaseDocument database) {
                    emitter.onComplete();
                }
            }));
            TestObserver<OElement> testObserver = elements
                    .doOnNext(System.out::println)
                    .test();
            session.begin();
            OElement element = session.newElement("MyClass");
            element.setProperty("num", 1);
            element.save();
            session.commit();
            testObserver.awaitCount(1)
                    .assertValueCount(1)
                    .assertValueAt(0, e -> e.getProperty("num").equals(1L));
        }
    }
}

Hi @wolf4ood,
I found the problem here, I tired to create the class with database user .it seems that the class (or any schema changes) should be created with server user while the live query should be created in database user. now it works.

1 Like