1

From this code:

String in = "E5D552ED-03AB-4AFA-B484-0D2C4FD64432";
UUID uuid = UUID.fromString(in);
String out = uuid.toString();

I get this output:

>  in: E5D552ED-03AB-4AFA-B484-0D2C4FD64432
> out: e5d552ed-03ab-4afa-b484-0d2c4fd64432

The issue is we use the String as the primary key on a row we insert into the DB before we create the UUID, and once it goes into the UUID we have an issue with getting back to that initial row since the DBMS is case-sensitive and we only have the UUID once it's created.

And I should have noted the input case is not consistently all upper or all lower. We work with a lot of vendors ... some send all caps, some all lower.

I'd rather not have to store an additional boolean on the side.

Anthony Raymond
  • 7,434
  • 6
  • 42
  • 59
Matt Felzani
  • 785
  • 10
  • 24
  • 3
    why dont compare as strings ingnoring the case? – ΦXocę 웃 Пepeúpa ツ Jan 26 '17 at 15:30
  • I am not aware of any specific `UUID` method to preserve case, but you can always invoke `toUpperCase` on your `out` if your `in` is consistently upper-cased. – Mena Jan 26 '17 at 15:31
  • how do i know the case it came from if i only have lower case. :) – Matt Felzani Jan 26 '17 at 15:32
  • 1
    i'm not sure that's the case re: two different UUIDs ... if they both toString() as the same string there is an element of logical equivalence to them. and unfair comment re: use the `UUID` data type in the DB. that's a great point but not applicable in this case. the DB is designed. i need help solving my specific problem, but thank you. – Matt Felzani Jan 26 '17 at 15:33
  • 7
    A UUID is essentially a 128 bits number that is represented as hexadecimal characters for clarity. Having them written uppercase or lowercase does not make a difference. – Arnaud Denoyelle Jan 26 '17 at 15:36
  • amaud, i think my post clearly explains why it does make a difference in my scenario. – Matt Felzani Jan 26 '17 at 15:37
  • 6
    As Arnaud states, a UUID is a number, not a string. If you need a case-sensitive string, a `UUID` is not what you want. You may *call* it a UUID, but it's not a `java.lang.UUID`. – Dave Newton Jan 26 '17 at 15:37
  • 2
    @MattFelzani Antoher solution is to make this column case-insensitive if your db supports it. imo it would make sense because it would be dangerous 2 have 2 UUID which differ only by their case. – Arnaud Denoyelle Jan 26 '17 at 15:39
  • 1
    @ArnaudDenoyelle I think the OP is stating that case sensitivity *does* matter--whether or not that's a Good Idea is a different debate. – Dave Newton Jan 26 '17 at 16:01
  • 1
    @MattFelzani It sounds like you have an X-Y problem here. You need a UUID *and* a column representing the client UUID. – Dave Newton Jan 26 '17 at 16:02

4 Answers4

3

You could extend UUID and then override toString to always give the representation of the string in all capitals.

@Override
public String toString() {
    return super.toString().toUpperCase();
}
ferahgo
  • 408
  • 1
  • 4
  • 11
  • that would be slick, but sometimes the initial insert is done with the string before it's turned into a `UUID`, and at that time it could be either case. thank you for the proposal, though! – Matt Felzani Jan 26 '17 at 15:55
  • then use database trigger to store it persistently in lowercase – Markus Jan 26 '17 at 16:15
  • 1
    @Markus The issue is that the clients' UUIDs are case-sensitive. The only way to do this is to have a DB-/app-level UUID and store the client UUID as a separate, case-sensitive string column. – Dave Newton Jan 26 '17 at 16:18
  • I would Override equals method instead. – xenteros Jan 26 '17 at 16:32
3

Taken from RFC4122 (and also described here) "The hexadecimal values "a" through "f" are output as lower case characters and are case insensitive on input."

Which in consequence means that your in & out is the same UUID. But the String representations are different.

So there are two options for you to do:

  1. Store it consistently as lower case String (either String.toLowerCase() or using database technology e.g. LCASE/LOWER to store it persistently)
  2. Second option would be to store the UUID in an optimized way (as a number) see here: how to store UUID as number

Be aware that option 2 is more complex, especially if you want to restore the String representation. And Option 1 may need cleanup of your DB if you have unique constraints or want to prevent data loss.

Community
  • 1
  • 1
Markus
  • 1,887
  • 18
  • 23
  • i had seen the RFC4122 notes and debated quoting them in the question. they are valuable to keep with the thread, thank you for adding the reference. – Matt Felzani Jan 26 '17 at 16:30
1

Just make the database column case-insensitive. For example with MySQL, use a collation ending with _ci : UUID CHAR(36) CHARSET ascii COLLATE ascii_general_ci.

dolmen
  • 8,126
  • 5
  • 40
  • 42
1

You're going to get much better performance out of your database if you store the UUID as BINARY(16), which is 16 bytes, rather than CHAR(36), which is 36 bytes (if you're using a character set that uses a single byte per character)

This is a similar problem to storing number is a varchar column. You can do it, but it's rarely the right way to go.