0

my java JPA Entity use the following code to generate its UUID

@Entity
public class Myclass {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    String id;

    String name;
}

In Oracle and in java as a string, the ID end up being something like this:

2c96cc2a52f9f9a90152fa6549f40008

a 32 hexadecimal character string.

I have to interact with some third party system that needs to save my ID in various places and it has to be the same. Unfortunately, their fields only allow 30-character string (any char, not only hexadecimal).

So I need my uuid to look like a 30-character or less string wherever it appears (in oracle, in java, in that third party system, etc).

What should i do so that the representation of that uuid uses all the alphanumerical characters ('ghi...z' but no weird characters) to be shorter and how to make sure this representation is what is visible in the DB and in the app?

Many Thanks

MikaelW
  • 1,145
  • 4
  • 11
  • 29
  • 1
    Define "any char". In fact, define "char". What does your third party define as a "char"? – fge Feb 19 '16 at 17:28
  • what i mean is i can have my ID use any alphanumerical characters: 0-9a-z as opposed to using only hexadecimal characters as it is currently the case. – MikaelW Feb 19 '16 at 17:30
  • UUID is not always guaranteed to be unique. – Tiny Feb 19 '16 at 17:50
  • 1
    @Tiny I don't think the OP really cares about that (and in real life, two identical UUIDs are pretty rare anyway); OP is really more interested in a way to obtain a bijection between his UUIDs and the third party requirements. At least that's what I understand. – fge Feb 19 '16 at 17:55
  • @Tiny -> https://stackoverflow.com/questions/1155008/how-unique-is-uuid?rq=1 – Ich Sep 27 '18 at 08:45

2 Answers2

2

If you're willing to deal with some odd-looking keys, encode the UUID in a base higher than 16, such as Base36 (all the letters and digits, can be case-insensitive) or Base64 (usually not URL-safe). If you want something URL-safe that's as compact as possible, you can use my implementation of Flickr-compatible Base58, which has specific helpers for encoding and decoding UUID objects.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152
  • Interesting, but (too lazy to make the calculation) can that actually reduce any UUID to a series of less than (or equal to) 30 characters, as the OP seems to require? – fge Feb 19 '16 at 17:38
  • @fge A UUID is 128 bits long, so anything more efficient than about base 20 should work (I can't remember the formula on my phone). IIRC Base58 won't take more than 21 characters. – chrylis -cautiouslyoptimistic- Feb 19 '16 at 17:44
  • so i added, in my entity class, a getId() and setId() method that convert from base16 string to base36 string and back (using BigDecimal). For example 2c96cc2a52fab0ae0152fab0d60d0000 <> 2n15kgjgtgcoa04nb6a1yxi4g. In my java app, its fine, but unfortunately in Oracle, the DB contain the long hexadecimal version :-( – MikaelW Feb 19 '16 at 18:09
  • ok, found a way that works and will post it below. Thanks for the help! – MikaelW Feb 19 '16 at 19:39
2

Thanks for the help! using base36 does the trick indeed. One more thing is necessary however to make sure the shorter ID is the one that appears in the DB as well:

 @PrePersist
 public void generateId() {
     String uuid_string = UUID.randomUUID().toString().replaceAll("-","");
     BigInteger big = new BigInteger(uuid_string, 16);
     String same_uuid_shorter_string = big.toString(36);
     id = same_uuid_shorter_string ; 
 }

(also get rid of the original id generator annotations)

MikaelW
  • 1,145
  • 4
  • 11
  • 29