arangodb-java-driver icon indicating copy to clipboard operation
arangodb-java-driver copied to clipboard

Support for `keepNull` and specifying the return type on `insertDocuments`

Open jebbench opened this issue 3 years ago • 3 comments

I'm trying to use collection.insertDocuments to support upsert but it doesn't support the keepNull property or specifying a custom return type.

Similar to #343.

I would like to be able to do this:

val options = DocumentCreateOptions().apply {
    overwriteMode(OverwriteMode.update)
    mergeObjects(true)
    keepNull(false)
    returnNew(true)
}

getCollection("my-collection")
    .insertDocuments(
        upserts,
        options,
        MyClass::class.java
    )
    .await()

jebbench avatar Mar 15 '21 18:03 jebbench

Unfortunately the current Java driver does not allow using keepNull on insert-update operations. This is a know limitation as you can see in the related javadoc.

About the return type, what would you like to achieve? Can you describe your use case more in detail?

rashtao avatar Mar 17 '21 10:03 rashtao

I'm building something roughly along the CQRS pattern where I have a command object that includes the operation (create or update) and the JSON (as a Jackson ObjectNode) to send to Arango.

My input is always an ObjectNode as that's what our audit system wants and our "managers" produce (so the user might send a request to the API to update field A, this is sent to the relevant "manager" class which will build a ObjectNode containing the change (updating field A might also mean updating field B (e.g. updatedAt)).

The end result of this is a list of changes that need to be applied to the database.

In the ideal world I would like to just run an upsert type operation where I can give Arango the changes and if the key exists it does an update and if not an insert - but to do this I would need to set keepNulls: false so I can delete attributes.

I'm currently making separate calls to insert and update (which isn't a problem really - it would just be nice if it could be done in one operation).

The update call is fine - I give it my ObjectNode and a Class; it applies the patch and returns the updated object deserialized to the provided class.

The insert call however doesn't have an option for passing the class I would like back - it always deserializes to the same type provided (so I give it an ObjectNode and it gives me back an ObjectNode). I'm currently getting around this by using Jackson to convert from ObjectNode to MyClass.

jebbench avatar Mar 17 '21 11:03 jebbench

As of now, you can workaround both problems performing an UPSERT with an AQL cursor: https://www.arangodb.com/docs/3.7/aql/operations-upsert.html

On the other side, implementing keepNull in the java driver document API is not trivial, since we should change the way the velocypack serializer deals with null values and this would result in a breaking change. I will open a new issue to address it.

About the return type, I agree to implement an overloaded version of insertDocument and insertDocuments that allow specifying it.

rashtao avatar Mar 18 '21 09:03 rashtao

Fixed in https://github.com/arangodb/arangodb-java-driver/releases/tag/v7.0.0-ALPHA.1

rashtao avatar Jan 20 '23 10:01 rashtao

Since vertion 7.0.0, keepNull behavior can be specified using Jackson API by:

  • adding annotations on related fields, or
  • registering custom serializers

see https://github.com/arangodb/arangodb-java-driver/blob/v7/docs/v7_java-reference-serialization.md.

Also, ArangoCollection.insertDocuments() has been overloaded with a variant accepting the return type that will be used as deserialization target, see https://github.com/arangodb/arangodb-java-driver/blob/v7/docs/v7_detailed_changes.md#api-methods-changes

https://github.com/arangodb/arangodb-java-driver/releases/tag/v7.0.0-RC.4

rashtao avatar Mar 21 '23 14:03 rashtao

Closing as fixed in version 7.0.0.

keepNull behavior can be specified using Jackson API by:

  • adding annotations on related fields, or
  • registering custom serializers

see https://github.com/arangodb/docs/blob/113c2351a0153171adfc74c313454af6bb5c7f08/drivers/java-reference-serialization.md.

Also, ArangoCollection.insertDocuments() has been overloaded with a variant accepting the return type that will be used as deserialization target, see https://github.com/arangodb/docs/blob/113c2351a0153171adfc74c313454af6bb5c7f08/drivers/java-changes-v7.md#api-methods-changes

rashtao avatar Apr 20 '23 12:04 rashtao