How to write bytearray to couchdb?

655 Views Asked by At

I want to send my object to couchdb using the ektorp java client. But I couldn't write my bytearray value to couchdb properly. My java object as follow:

enter image description here

If I convert bytearray to String:

enter image description here

The metadata value is saved on couchdb as "AgIGZm9vBmJhegA=" (base64), This means that "foobaz". Why is my bytearray value changed?

enter image description here

My example code :

private CouchDbInstance dbInstance;
private CouchDbConnector db;    

    ... 

    Map<String, Object> doc = new HashMap<>();
    doc.put("_id", "foo.com:http/");

    byte[] serilazeData = IOUtils.serialize(writer, fieldValue);
    doc.put("metadata", serilazeData);

    ...
    db.update(doc);

My main code block

    public void put(K key, T obj) {

        final Map<String, Object> doc = new HashMap<>();
        doc.put("_id", key.toString());

        Schema schema = obj.getSchema();

        List<Field> fields = schema.getFields();
        for (int i = 0; i < fields.size(); i++) {
          if (!obj.isDirty(i)) {
            continue;
          }
          Field field = fields.get(i);
          Schema.Type type = field.schema().getType();
          Object fieldValue = obj.get(field.pos());
          Schema fieldSchema = field.schema();

          fieldValue = serializeFieldValue(fieldSchema, fieldValue);
          doc.put(field.name(), fieldValue);
        }
        db.update(doc);

      }

      private Object serializeFieldValue(Schema fieldSchema, Object fieldValue ){
        ...
            byte[] data = null;
            try {
              SpecificDatumWriter writer = getDatumWriter(fieldSchema);
              data = IOUtils.serialize(writer, fieldValue);
            } catch (IOException e) {
              LOG.error(e.getMessage(), e);
            }
            fieldValue = data;
         ...
        return fieldValue;
      }
3

There are 3 best solutions below

1
L. Gleim On

The value is the base64 encoded string "foobaz". You should probably post your code as well to get any meaningful feedback regarding this issue.

edit: Now that you provided code, is it possible, that the object you are trying to update already exists in the database? If yes you need to get it first or provide the proper existing revision id for the update. Otherwise the update will be rejected.

0
NickN On

CouchDB stores JSON documents, and JSON does not support byte arrays, so I guess Ektorp is applying its own Base64 conversion during conversion of your object to JSON, before sending to CouchDB, and maybe that is skipping some characters in the byte array.

You might prefer to sidestep the Ektorp behaviour by applying your own Base64 serialisation before calling Ektorp, and then deserialise yourself after fetching the document from CouchDB. Or you could use something like Jackson, which will handle the object/JSON conversion behind the scenes, including byte arrays.

0
Henrik Barratt Due On

Ektorp uses Jackson for json serialization, I think jackson defaults to base64 for byte arrays. As long as you read/write with Ektorp you should not have any problems.

But I see in your code that you have some kind of type system of your own so that complicates things. I suggest you use POJOS instead of rolling your own since you won't get much help from ektorp and jackson if you are doing it yourself.