orientdb icon indicating copy to clipboard operation
orientdb copied to clipboard

Saving a vertex using studio or REST-API and then adding new edges with the Java API breaks outward facing linkbags and/or crashes DB

Open theghostrecords opened this issue 3 years ago • 1 comments

OrientDB Version: 3.2.6 (Tried 3.2.9 as well)

Java Version: 11

OS: alpine:3.16

Expected behavior

Editing a vertex through OrientDB studio (with the edit view) and then pressing save should update the document but not convert the types of "outward" facing Linkbags. Additionally LinkLists should be mapped to OType.LinkList when retrieved through the Java API.

Actual behavior

Linkbags with direction "out" are converted to Linklists when saving in orientdb studio edit mode. When retrieving the vertex through the Java graph API (Tinkerpop 2.6) or document API the field is mapped to OType.EmbeddedList. When writing to a field and adding a new edge to the vertex using the Java API (OrientVertex#addEdge) the LinkList is converted to an EmbeddedList and the new link is corrupt.

An interesting observation: We add a property and an edge within the same transaction. If we remove the invocation of OrientVertex#setProperty and only add the edge, the database crashes (Found null entry in ridbag). When we set a property within the same transaction the change is written to the db and a corrupted edge is appended to the EmbeddedList. Maybe related to: https://github.com/orientechnologies/orientdb/issues/9767

Example project using two docker services and the demodb

I created an example project where it can be easily reproduced with the demo database - follow the steps in the readme: https://github.com/theghostrecords/orientdb-example

Steps to reproduce

  • For a concrete example see the readme in the linked example project

Using a theoretical example vertex and edge type:

  • Example vertex: V1 with property out_HasExample (type LinkBag)
  1. Open V1 in edit mode
  2. Press the Save button in the upper right corner
  3. Go back to the "Browse" panel
  4. Query V1 in and see that the type of out_HasExample has changed to LinkList (out_HasExample.type())
  5. Add a new property and a new out_HasExample edge to V1 through the Java API
  6. Query V1 in orientdb studio and see that the type of out_hasExample has changed to EmbeddedList.
  7. Open edit mode and see that the new link is 'corrupt' in out_HasExample.

It does look like the fields retrieved from the server is mapped to the wrong OType. Could this be a mapping and serialization issue on the server side?

Example:

Before: image

After saving in edit mode: image (1)

After writing a new edge through the Java API image (2)

image (3)

theghostrecords avatar Sep 19 '22 08:09 theghostrecords

When only writing a new edge within the transaction the db crashes with:

db_1   | 2022-09-19 08:57:16:832 SEVER {db=demodb} Found null entry in ridbag with rid=#-1:-1 [ORecordSerializerBinaryV1]Exception `1B3B2FC2` in storage `plocal:/orientdb/databases/demodb`: 3.2.6 (build 92f0b7006cf27a25e80d0ef401ce09618f64189d, branch UNKNOWN)
db_1   | com.orientechnologies.orient.core.exception.OSerializationException: Found null entry in ridbag with rid=#-1:-1
db_1   | 	DB name="demodb"
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.HelperClasses.writeEmbeddedRidbag(HelperClasses.java:378)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.HelperClasses.writeRidBag(HelperClasses.java:354)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV1.writeRidBag(ORecordSerializerBinaryV1.java:731)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV1.serializeValue(ORecordSerializerBinaryV1.java:1020)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV1.serializeValues(ORecordSerializerBinaryV1.java:404)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV1.serializeDocument(ORecordSerializerBinaryV1.java:462)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinaryV1.serialize(ORecordSerializerBinaryV1.java:483)
db_1   | 	at com.orientechnologies.orient.core.serialization.serializer.record.binary.ORecordSerializerBinary.toStream(ORecordSerializerBinary.java:132)
db_1   | 	at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.commitEntry(OAbstractPaginatedStorage.java:5956)
db_1   | 	at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.commit(OAbstractPaginatedStorage.java:2368)
db_1   | 	at com.orientechnologies.orient.core.storage.impl.local.OAbstractPaginatedStorage.commit(OAbstractPaginatedStorage.java:2191)
db_1   | 	at com.orientechnologies.orient.core.db.document.ODatabaseDocumentEmbedded.internalCommit(ODatabaseDocumentEmbedded.java:1978)
db_1   | 	at com.orientechnologies.orient.core.tx.OTransactionOptimistic.doCommit(OTransactionOptimistic.java:621)
db_1   | 	at com.orientechnologies.orient.core.tx.OTransactionOptimistic.commit(OTransactionOptimistic.java:114)
db_1   | 	at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.commit(ODatabaseDocumentAbstract.java:1593)
db_1   | 	at com.orientechnologies.orient.core.db.document.ODatabaseDocumentAbstract.commit(ODatabaseDocumentAbstract.java:1563)
db_1   | 	at com.orientechnologies.orient.server.OConnectionBinaryExecutor.executeCommit38(OConnectionBinaryExecutor.java:1549)
db_1   | 	at com.orientechnologies.orient.client.remote.message.OCommit38Request.execute(OCommit38Request.java:141)
db_1   | 	at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.sessionRequest(ONetworkProtocolBinary.java:355)
db_1   | 	at com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary.execute(ONetworkProtocolBinary.java:239)
db_1   | 	at com.orientechnologies.common.thread.OSoftThread.run(OSoftThread.java:68)
db_1   | $ANSI{green {db=demodb}} Error on transaction commit `1B3B2FC2`

theghostrecords avatar Sep 19 '22 08:09 theghostrecords

Hi,

This should be already fixed in 3.2.10, I tried to reproduced it without any success in that release, also from the description of the error, that the type of the out collection resulted changed after the save that seems like an error in the json deserialization, some changes on type management in json has been reverted in 3.2.10, so it does make sense that this error was also fixed.

Regards

tglman avatar Sep 27 '22 14:09 tglman

Hey, thanks for having a look. Great! I'll try the newer version tomorrow and update you on how it goes.

Thanks again. Regards

theghostrecords avatar Sep 27 '22 15:09 theghostrecords

Hi, sorry for the long wait. Took a while before I could test this in a proper environment.

As you already stated this problem seems to be fixed in 3.2.10. A deserialization bug sounds plausible.

I'll close the issue. Should it be labeled with something specific?

Thanks for your quick assistance. Kind regards

theghostrecords avatar Oct 06 '22 13:10 theghostrecords