Prefer UUID for your Primary Key
Share this post:
Enjoy this Post?You'll love our newsletter!
In my last post
I discussed the downsides of using numerical types
for the primary key of an entity. We should avoid these issues all together by using
UUID instead and in this post I
will discuss the up- and downsides of this approach.
Using a UUID as the primary ID is simple:
@Entity class Flat( @Id val id: UUID = UUID.randomUUID() )
Generate the ID on the application
Similar to numerical ids we can generate it on the database as well. But for
UUID this is not necessary. The reason we
did this in the first place is that we needed to make sure that an ID is not used twice. A collision of
UUID is very
unlikely to occur.
And what do we do when such error happens? We don’t need to establish any special handling of it. We throw an exception, cancel the transaction and let the client redo the operation. Like we would always do when something happens that we can’t handle.
But we get extraordinary benefits from
We don’t need to generate the
UUID on the database. We don’t even need to generate it on the backend. We can create it
in the client. And this enables the client to create new entities without synchronizing them to the backend. This
enables us to make the client very resilient to network issues. E.g. I implemented such behavior in a game I developed
and that enabled us to support playing the game even in unstable environments like when you play on the train and drive
through tunnels. It is an awesome experience for the users and does not require a lot of work on the application to
Easier (Unit) Testing
When you generate the
UUID on the client or server you have much more control over it. And this is beneficial when you
want to write unit tests for your entities. You can simply use the constructor. Generating it on the database relied on
reflection and in the runtime between the setting of the id and the creation of the object it is in an unstable
state. Have a look at the “Collection Problem” in my previous post
UUIDs are unhandy. Remembering that
E209C805-C7D5-4C7A-8F02-37BEA845A405 is the ID of the entity you look at is of
course harder than remembering
2837. This is a downside and everyone needs to decide whether that is a strong
UUID are larger than
Int. You can do a whole evaluation of this aspect. You can even fill pages and whole
blogs about it. But I don’t do that. In relation to all the other kind of data that we store nowadays it is a waste of
time and energy. Space - in this scale - does not matter for 99% of the applications out there. If you work in an
environment where it matters, sure, do the evaluation and make a proper decision. But for most of the developers our
there it shouldn’t matter at all.