Search code examples
playorm

Is there any converter for UUID type in playORM?


I would like to map a field with type UUID. I am generating it like follows:

import java.util.UUID; UUID id = UUID.randomUUID();

Is there any problem in using this? What converter could I use for this?


Solution

  • random != unique. At very very very high numbers, you may collide. Some people are ok with this....I prefer to avoid it as even though the probability could be somewhere near 1 in 1 billion, if it happens, debugging it is a PITA.

    Also, At very very very high numbers, you get more likely to collide.

    Read this link

    http://johannburkard.de/blog/programming/java/Java-UUID-generators-compared.html

    Basically, I looked at his code once and to be unique, it is really mac address + UNIQUE timestamp within that computer, so two threads are not allowed to grab the same timestamp.

    In fact, if you use @NoSqlId, it is actually using unique counter from timeA + hostname so it is unique within one cluster. One client uses hostnames of a1, a2, a3 which keep the primary key nice and short. I never thought about it before but if I added @NoSqlIndex on the key, I could query ranges of keys and they are in order of time.

    I should probably create another generator that is time based so people can use as primary key and query time ranges(add an issue if this will be useful for you as I work in order of what clients need rather than what I think is needed).

    For the above to answer your question. you can create the Converter and when going from byte[] to UUID, you can just use

    public static UUID nameUUIDFromBytes(byte[] name)
    

    Going backwards though, you need to do the opposite of that function which from the java source code is

    public static UUID nameUUIDFromBytes(byte[] name) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException nsae) {
            throw new InternalError("MD5 not supported");
        }
        byte[] md5Bytes = md.digest(name);
        md5Bytes[6]  &= 0x0f;  /* clear version        */
        md5Bytes[6]  |= 0x30;  /* set to version 3     */
        md5Bytes[8]  &= 0x3f;  /* clear variant        */
        md5Bytes[8]  |= 0x80;  /* set to IETF variant  */
        return new UUID(md5Bytes);
    }
    

    thanks, Dean