Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java Document api can not update a record with an immutable binary field #7146

Closed
jackiszhp opened this issue Feb 3, 2017 · 6 comments
Closed
Assignees
Labels
Milestone

Comments

@jackiszhp
Copy link

jackiszhp commented Feb 3, 2017

OrientDB Version: 2.2.15

Java Version: 1.8

OS: does not matter.

Expected behavior

should allow update.

Actual behavior

with java document api, the update failed:

com.orientechnologies.orient.core.exception.OValidationException: The field 'Test1.s' is immutable and cannot be altered. Field value is: [B@579cee6b
DB name="C"
DB name="C"
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:422)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.throwSerializedException(OChannelBinaryAsynchClient.java:442)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.handleStatus(OChannelBinaryAsynchClient.java:393)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.beginResponse(OChannelBinaryAsynchClient.java:275)
at com.orientechnologies.orient.client.binary.OChannelBinaryAsynchClient.beginResponse(OChannelBinaryAsynchClient.java:167)
at com.orientechnologies.orient.client.remote.OStorageRemote.beginResponse(OStorageRemote.java:2201)
at com.orientechnologies.orient.client.remote.OStorageRemote$12.execute(OStorageRemote.java:769)
at com.orientechnologies.orient.client.remote.OStorageRemote$12.execute(OStorageRemote.java:765)
at com.orientechnologies.orient.client.remote.OStorageRemote$1.execute(OStorageRemote.java:165)
at com.orientechnologies.orient.client.remote.OStorageRemote.baseNetworkOperation(OStorageRemote.java:238)
at com.orientechnologies.orient.client.remote.OStorageRemote.asyncNetworkOperation(OStorageRemote.java:157)
at com.orientechnologies.orient.client.remote.OStorageRemote.updateRecord(OStorageRemote.java:749)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.executeSaveRecord(ODatabaseDocumentTx.java:2190)
at com.orientechnologies.orient.core.tx.OTransactionNoTx.saveRecord(OTransactionNoTx.java:178)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.save(ODatabaseDocumentTx.java:2716)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.save(ODatabaseDocumentTx.java:103)
at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:1802)
at com.orientechnologies.orient.core.record.impl.ODocument.save(ODocument.java:1793)

Steps to reproduce

At first, setup the following structure:

create class Test1 extends V
create property Test1.a integer
create property Test1.s binary (readonly true)

Then,
with sql, it is OK to update Test1.
update Test1 set a=2

but with java document api, it will fail, it says Test1.s is immutable.
In fact, if Test1.s is integer, then no problem. And if Test1 is not a Vertex, but a general class, then no problem. The problem occurs only when Test1 is a vertex and it has an immutable binary field.

I have not looked at the code at the server side, so I have no idea, what is really wrong.

Jack.

@lvca
Copy link
Member

lvca commented Feb 3, 2017

Could you please try the last 2.2.x (2.2.15 now)? Release 2.1.x is not supported anymore without a contract, sorry.

@jackiszhp
Copy link
Author

jackiszhp commented Feb 3, 2017

Indeed, I am using 2.2.15, java document api.

The previous issue occurs when I use remote url, if I change the url to plocal, then I got

java.lang.ClassCastException: [B cannot be cast to java.lang.Number
at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV0.serializeValue(ORecordSerializerBinaryV0.java:680)
at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV0.serialize(ORecordSerializerBinaryV0.java:383)
at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinary.toStream(ORecordSerializerBinary.java:99)
at com.orientechnologies.orient.core.record.impl.ODocument.toStream(ODocument.java:2378)
at com.orientechnologies.orient.core.record.impl.ODocument.toStream(ODocument.java:664)
at com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx.executeSaveRecord(ODatabaseDocumentTx.java:2157)

And this exception is not caught on updating a record, but on saving a record for the first time. By the way, in my test, my binary data is just 18 bytes. I would say this is some very basic operation, why I got exception? Do I have something very wrong? By the way, if the Test1.s is not readonly, then there is no such exception.

@jackiszhp
Copy link
Author

I am using 2.2.15, not 2.1.15, sorry for the typo.

@lvca lvca added the bug label Feb 3, 2017
@tglman
Copy link
Member

tglman commented Feb 7, 2017

hi,

Looking to the exceptions seems that you have a miss-match from the type on the schema and the field you set, will be cool if you can provide a small test case that reproduce the problem.

Regards

@tglman tglman added this to the 2.2.x (next hotfix) milestone Feb 15, 2017
@jackiszhp
Copy link
Author

Upon your request, I made the following class:

public class TestReadOnly {

static String url_DB
        = //"plocal:/..../databases/C";
        "remote:..../C";
static String user_DB = "admin", password_DB = "admin";

public static class MyCustomRecordFactory implements ODatabaseThreadLocalFactory {

    private OPartitionedDatabasePool pool;

    public MyCustomRecordFactory(String url, String user, String password) {
        pool = new OPartitionedDatabasePool(url, user, password);
    }

    @Override
    public ODatabaseDocumentInternal getThreadDatabase() {
        return pool.acquire();
    }
}

static MyCustomRecordFactory rf;
ODocument doc;

void save2DB(Test1 t1) {
    ODatabaseDocument db;
    if (rf == null) {
        rf = new MyCustomRecordFactory(url_DB, user_DB, password_DB);
    }
    db = rf.getThreadDatabase();
    try {
        if (null == doc) {
            doc = new ODocument("Test1");
        }
        doc.field("a", t1.a);
        doc.field("s", t1.s);
        doc.save();
    } finally {
        db.close();
    }
}

static class Test1 {

    int a;
    byte[] s;
}

void testUpdate() {
    try {
        Test1 t1 = new Test1();
        t1.a = 10;
        t1.s = new byte[10];
        Random r = new Random();
        r.nextBytes(t1.s);
        System.out.println("\n\n\nwill save 1st time");
        save2DB(t1);
        System.out.println("\n\n\nwill save 2nd time");
        save2DB(t1);
        System.out.println("everything is good");
    } catch (Throwable ex) {
        ex.printStackTrace();
    }

}
public static void main(String[] args){
    
    new TestReadOnly().testUpdate();
}

}
For DB structure
/*
create class Test1 extends V
create property Test1.a integer
create property Test1.s integer (readonly true) no problem
create property Test1.s binary (readonly true)
insert vertex Test1 set a=10,s="12431234"
update Test1 set a=11

the above states are all good.
*/
when readonly constraint is removed, everything is OK.

@tglman
Copy link
Member

tglman commented Feb 28, 2017

hi @jackiszhp,

I checked it found the root of the problem and fixed it, the fix will be released in 2.2.18.

Closing this

@tglman tglman closed this as completed Feb 28, 2017
@santo-it santo-it modified the milestones: 2.2.18, 2.2.x (next hotfix) Apr 4, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

4 participants