Let's start with an example: we have an entity: Book. It has unique identity: Isbn - a value object that wraps a String. This is an UUID.

The Book entity also needs a surrogate id from the repo (sql db). We need it so we can e.g. find the books in faster way, since databases find by number faster then by string.

From what I read, the surrogate key should be hidden from the Books interface. But we want to use it, to locate books much faster.

How to deal with this in a proper way?

[A] We can simply add a getSurrogateId() (or any better name) in the Book. This pollutes the entity, but its KISS.

[B] We can have the repo responsible for finding the surrogate keys for the natural ones. For example, BookRepository may have the following method:

long toSurrogateKey(Isbn isbn) {
     // lookup the cache
     // if not found, lookup the db

to return the surrogate key - of course, these values can be cached locally, so we do not need to search db every time. This method should not be public (right)?

[C] We can go even further: to think about surrogate key as a repository specific one. Book may be an interface, and SqlBook may be an repository-made implementation. This SqlBook implementation may then store any additional information needed for the repository. In this case, we would have the surrogate key as one of the properties of SqlBook - and we do not care it is visible, as users of SqlBook only sees it as a Book, i.e. not knowing about the surrogate id.

So above method becomes (defined in SqlBook class):

long toSurrogateKey(Book book) {
     return ((SqlBook)book).getSurrogateId();

The only drawback here is that Book (and other entities) must be created by a Factory that is repository-aware. In other words, we would need to have SqlFactory implementation of some factory that creates SqlBooks for us.

Any wisdom on this?

1 Answer 1


We need it so we can e.g. find the books in faster way, since databases find by number faster then by string.

Surrogate keys should primarily be added because they provide you a uniform way for building your primary keys, not because of any hypothetical performance issues. They will help you to avoid having business data like an Isbn distributed over half of your model in separate places because you misuse them as foreign keys.

"From what I read, the surrogate key should be hidden from the Books interface".

Maybe you just misunderstand the purpose of this? Surrogate keys are technical details which should be hidden when discussing the model with your domain experts, but it is perfectly ok to see them when you change your viewpoint to the implementation of the model. So go with [A], but make sure the getSurrogateId() accessor is not visible in your graphical form of your domain model.

  • Thanx! It's not hypothetical - it's implementation fact. But maybe it's not a 'surrogate key', I admit, just an 'additional technical/implementation information' of the Book. Anyway, I believe this is not just a matter of graphical visibility. The API should also express to developers the right usage. So if we expose this method as public one, developers may start using it for other stuff, instead of the real key. Then we do not need Isbn to be nothing more than just a simple value object. Any thought/experience?
    – lawpert
    Oct 31, 2014 at 15:52
  • Honestly, your fears sound superstitious to me. I work with "technical keys" instead of "business keys" since almost 20 years and from that experience I can tell you you should encourage your devs to use the technical primary key instead of a business key whereever possible. The less places you use the business key as a unique identifier, the less places you will have to change when something changes in your business key (which will happen).
    – Doc Brown
    Oct 31, 2014 at 16:03
  • 1
    Don't get me wrong. I also work with 'technical' keys all my life:) The focus here is not to have it working, but trying to figure the DDD concepts in practice. And the DDD says opposite, that we actually should use domain primary key in the code, too, as part of ubiquitous language.
    – lawpert
    Oct 31, 2014 at 16:33
  • 1
    @lawpert: so as I suspected - just your interpretation. Try to interpret that part differently - problem solved.
    – Doc Brown
    Nov 1, 2014 at 6:59
  • 1
    Hey @Doc Brown, it's not like that. Vernon (and others as well) says that this kind of keys should be hidden from the interface. This is not my interpretation. Now, I have added additional 'developers' concern to this story (since I am having that problem) where developers have 'polluted' the system using technical key where it should not make sense. All what you are saying I do understand, but trying to figure if there is a better way, that could solve more real-life problems. So I am not fighting with you, I am just asking these questions myself as well.
    – lawpert
    Nov 1, 2014 at 11:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.