Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a byte array from couchbase in Spring

I have a simple Object that I am trying to read/write into couchbase (using spring data). Here is the object:

@Document
public class CacheObject {
  @Id
  private String id;
  private byte[] data;

  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public byte[] getData() {
    return data;
  }
  public void setData(byte[] data) {
    this.data = data;
  }  
}

I try to read/write it using the Couchbase template:

  @Test
  public void test2() throws Exception {
    CacheObject o = new CacheObject();
    o.setId("test1");
    o.setData("test123".getBytes());
    CouchbaseTemplate t = c.couchbaseTemplate();

    t.save(o);
    CacheObject o2 = t.findById("test1", CacheObject.class);
    System.out.println("COOL " + new String(o2.getData()));
  }

The template comes from a config that extended AbstractCouchbaseConfiguration.

The write works fine, I see the base64 encoded value in couchbase. The read throws an Exception:

org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type byte for value 'd293'; nested exception is java.lang.NumberFormatException: For input string: "d293"
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:189)
    at org.springframework.core.convert.support.StringToArrayConverter.convert(StringToArrayConverter.java:63)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:35)
...

I can get around this by using a custom reader (This is in my config that extended AbstractCouchbaseConfiguration). Using this code, everything works.

 public CustomConversions customConversions() {
   return new CustomConversions(Arrays.asList(StringToByteConverter.INSTANCE));
  }

  @ReadingConverter
  public static enum StringToByteConverter implements Converter<String, byte[]> {
    INSTANCE;

    @Override
    public byte[] convert(String source) {
      return Base64.decodeBase64(source);
    }
  }

Am I doing something wrong?

I have tried 1.2.2 and 1.3.0.M1 and both give the same results.

Thanks

like image 779
KevinK Avatar asked Apr 09 '26 10:04

KevinK


1 Answers

I think you are doing this correctly. If you observe the json that got stored in Couchbase, it looks like this:

{ "_class": "CacheObject", "data": "dGVzdDEyMw==" }

When you try to convert the data property back to a CacheObject, it is attempting to convert the string above to a primitive byte array, hence the NumberFormatException. Is there something you are trying to accomplish by storing a byte array the way you are doing it?

According to the approach you are testing, I think you need a custom converter to transform the string version of the byte array as expected, because couchbase template doesn't support this type by default. See this link for supported types:

http://docs.couchbase.com/developer/dev-guide-3.0/using-json-docs.html

Hope this helps.

like image 182
tacree Avatar answered Apr 14 '26 19:04

tacree



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!