Search code examples
javariak

How to use non-String @RiakKey?


Is it possible to use a field that isn't a String as a @RiakKey? Here's what I have:

public class DomainObject {
  @RiakKey private UUID objectId;
}

Unfortunately, the current (v1.4.0) java client bombs out setting the key on deserialization:

java.lang.IllegalArgumentException: Can not set java.util.UUID field com.company.DomainObject.objectId to java.lang.String
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) ~[na:1.7.0_25]
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) ~[na:1.7.0_25]
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) ~[na:1.7.0_25]
at java.lang.reflect.Field.set(Field.java:741) ~[na:1.7.0_25]
at com.basho.riak.client.convert.reflect.ClassUtil.setFieldValue(ClassUtil.java:45) ~[riak-client-1.4.0.jar:na]
at com.basho.riak.client.convert.reflect.AnnotationInfo.setRiakKey(AnnotationInfo.java:149) ~[riak-client-1.4.0.jar:na]
...snip

Is there any way to do this without degrading the domain object by changing the UUID to a String?


Solution

  • Using the default JsonConverter and annotation processing? No.

    Keys is Riak are strings (ok, technically, some bytes ... but still certainly nothing that UUID object is going to automagically convert into).

    The easiest way (and quite frankly, faster way given the overhead of reflection) is to write your own Converter<T> and use that instead of the default JsonConverter. You can either forego our annotation processing or use it for everything but the UUID.

    It's fairly straight forward and obviously you can look at the source for JsonConverter on github[1] to see how it currently works. There's nothing very fancy there; there's some utility methods that do the annotation processing we use Jackson for the JSON conversion.

    I also wrote a cookbook entry that covers writing and using a custom converter, it's in the wiki on github[2].

    [1] https://github.com/basho/riak-java-client/blob/1.4.1/src/main/java/com/basho/riak/client/convert/JSONConverter.java

    [2] https://github.com/basho/riak-java-client/wiki/Using-a-custom-Converter

    Edit to add: The missing piece that really would solve your problem is if the @RiakKey annotation processing supported methods, which unfortunately it doesn't at the moment. It is something we're planning to add in the v2.0 rewrite of the client which we're currently working on.

    Updated 10/04/2013: I needed to do a maintenance release for the 1.1.x and 1.4.x branches of the client, so I decided to add this as well. 1.1.3 and 1.4.2 will support getter/setter methods for @RiakKey. See: https://github.com/basho/riak-java-client/pull/293