So, I read someone’s blog post about the pros and cons of using UUIDs as primary keys. I am a big believer in using UUIDs as primary keys for domain objects in the DB. Having used them quite a bit in my projects, I wanted to debate a couple of the cons listed in the original post.
1. Performance can be an issue: Yes, it can, but grabbing a sequence from the DB creates a bigger issue (2 calls per new insert, depending on the RDBMS platform). This can be easily remedied by writing a simple UUID pool object which generates the UUIDs in batch, and doles them out on request. When the pool runs low/out, regenerate.
2. Ordering/Sorting. Indeed, you really cannot order by the primary key in the case of a UUID. But then again, why does one usually order by primary key? Sequential primary keys tend to indicate the order of entity creation. Good DB design principles include having a created_date and a modify_date column as part of the entity (depending on your needs and requirements, of course, but I’d say this is mostly true). With this in mind, you CAN order by the create date.
3. cannot test if a record has already been persisted by checking if the Id field has been set. Uhm, you can write a @GenericGenerator to generate the uuid if you’re using a JPA provider other than hibernate, and it wouldn’t be hard at all. The UUID is only set upon insert call to the DB, so you can do this check. But the OP is right, I question a design that checks for the existence of a PK being set.
Now, not all is roses of course. Using the pre-generated strategy in point #1 means that once in a while you may be generating 100 UUIDs to populate the pool, creating a slight response lag for that 1 in 100 new inserts (if you have a 100 UUID pool for example). This is akin to a GC cleanup cycle, though less harsh I think.
Depending on the DB platform, sorting by date columns can be slower, though I argue not so slow as to affect performance significantly.
One thing that annoys operations folks who may be tracking a transaction of some kind through multiple systems, with each transaction entity (whatever that is for your case) being marked with a UUID. So, rather than using a simple number as a tracking tag, you’re using a somewhat-hard-to-read 32 character (or more with hyphens) string.
Other than that, I think UUIDs are (generally) the best way to go with PKs. Personally, I make it a general rule to treat PKs as an implementation issue with using RDBMs and not an actual part of the persisted domain entity.