avatarNicklas Millard

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3101

Abstract

below.</p><figure id="8a5d"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*VVz4sfbnDpZZunN3NdXozg.png"><figcaption></figcaption></figure><p id="4e64">Let’s walk thru this code, as every change from the TerribleBook to FixedBook might not be obvious to everyone.</p><p id="ea58">We make the constructor private and instantiate new objects using the static factory method. This allows us to abstract the instantiation logic from the caller and even provides us the opportunity to use polymorphism — we might want to return a Null Object instead of throwing.</p><p id="4c43">Notice we’re still taking the id as a constructor parameter. But <b><i>we</i></b> are in charge of generating and providing the id (on line 18). Not the database.</p><p id="d932">The entity id datatype is changed from int to string — simply to allow the possibility to use something that is meaningful to the business. Do however watch out for performance issues and the consequences of using strings as IDs.</p><p id="c6bd">The <code>Guid.NewGuid().ToString("D")</code> just ensures we’ll get a hyphen formatted GUID. I like using GUIDs, but you’re free to build your own ids which ever way makes sense to your business and application needs.</p><h2 id="85ed">UPDATE</h2><p id="432c">Please note that I’m not talking about what to use as primary key…</p><p id="fefc">Also, I make no claim my solution is without trade-offs.. Better entity design traded with potentially worse performance. I know that’s something DBAs will lose their minds over, but so be it.</p><p id="ab99">You’ll have to make your own decisions about what’s best in your specific scenario.</p><div id="f38a"><pre><span class="hljs-section">Resources for the curious --------------------------</span></pre></div><div id="d431"><pre><span class="hljs-keyword">When</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">where</span> <span class="hljs-keyword">to</span> determine the ID <span class="hljs-keyword">of</span> en entity <span class="hljs-keyword">by</span> Matthias Noback</pre></div><div id="75c6"><pre>CQS versus <span class="hljs-keyword">server</span> <span class="hljs-keyword">generated</span> IDs <span class="hljs-keyword">by</span> Mark Seemann</pre></div><div id="7a81"><pre>Why <span class="hljs-keyword">Auto</span> Increment <span class="hljs-built_in">Is</span> A Terrible Idea <span class="hljs-keyword">by</span> Clément Delafargue</pre></div><div id="6420"><pre><span class="hljs-type">UUID</span> <span class="hljs-keyword">or</span> GUID <span class="hljs-keyword">as</span> <span class="hljs-keyword">Primary</span> Keys? Be Careful! <span class="hljs-keyword">by</span> Tom</pre></div><div id="7953"><pre><span class="hljs-keyword">SQL</span> <span class="hljs-keyword">Server</span>: <span class="hljs-keyword">Natural</span> Key Versus Surrogate Key <span class="hljs-keyword">by</span> Gregory A. Larsen</pre></div><figure id="fac8"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*TMZihqPx2zFjYDyIZ5tKTQ.png"><figcaption></figcaption></figure><div id="a3d8" class="li

Options

nk-block"> <a href="https://readmedium.com/refactoring-from-trash-to-solid-74b10005ccd3"> <div> <div> <h2>Refactoring From Trash to SOLID</h2> <div><h3>Amp up your code quality, the easy way.</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*0PgsZ6yvh4LobC9zmTqKyg.png)"></div> </div> </div> </a> </div><div id="9c92" class="link-block"> <a href="https://readmedium.com/5-ways-to-replace-if-else-statements-857c0ff19357"> <div> <div> <h2>Better Software Without If-Else</h2> <div><h3>5 Ways to Replace If-Else. Beginner to advanced examples</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*3Ju0VYbFi0w0rVYt9RT_vw.png)"></div> </div> </div> </a> </div><div id="8a67" class="link-block"> <a href="https://readmedium.com/stop-using-if-else-statements-f4d2323e6e4"> <div> <div> <h2>Stop Using If-Else Statements</h2> <div><h3>Write clean, maintainable code without if-else.</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*xUWTgHxBR4P_lYWzqGgImQ.png)"></div> </div> </div> </a> </div><div id="af6c" class="link-block"> <a href="https://readmedium.com/stop-checking-for-nulls-5f9f857ddf72"> <div> <div> <h2>Stop Checking for Nulls</h2> <div><h3>Null Object Pattern, Factory Methods — Let’s see some production ready code!</h3></div> <div><p>medium.com</p></div> </div> <div> <div style="background-image: url(https://miro.readmedium.com/v2/resize:fit:320/1*PEkfn8OvgbNMSrHUPVIYUQ.png)"></div> </div> </div> </a> </div><figure id="b109"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*LZ0-rAawOB4iv6uI.png"><figcaption></figcaption></figure><p id="cc49"><b>Nicklas Millard</b> is a software development engineer in one of the fastest-growing banks, building mission-critical financial services infrastructure.</p><p id="7bfa">Previously, he was a Big4 Senior Tech Consultant developing software for commercial clients and government institutions.</p><blockquote id="71d7"><p><a href="https://www.youtube.com/channel/UCaUy83EAkVdXsZjF3xGSvMw">New YouTube Channel (@Nicklas Millard)</a></p></blockquote><blockquote id="f1a4"><p><i>Connect on <a href="https://www.linkedin.com/in/nicklasmillard/">LinkedIn</a></i></p></blockquote></article></body>

PRACTICAL PROGRAMMING ADVICE

Three Issues With Using Database Generated IDs

Stop letting the database be in charge of your application

You’ve probably let databases generate IDs for your entities at least once.

But, what if I told you there’s an alternative when developing applications?

I’m sure this stands in sharp contrast to what you learned in the Relational Databases 101 college course and the countless youtube tutorials you’ve watched when learning how toCREATE TABLE UsingTerribleIds ().

Generate your IDs at the application level. Not at the persistence level.

That’s it. You’re free to go on your merry way.

(please note that entity ID is not necessarily a database primary key)

Or, stay put if you want to know more about why database generated entity IDs may be troublesome and want to learn how I approach ID generation at client projects.

So, what’s the issue with having the database generate your entities’ IDs?

1 What’s most problematic is you’re delegating an important aspect of your domain to third party software.

2You’re likely to apply some bad practices while designing your entity classes just to make it easier working with a persistence framework, such as EntityFramework in C# .NET.

One of the worst offenders I see junior programmers do is having public ID setters.

Just terrible to witness.

A public setter tells the world it’s okay to change this entity’s ID — which may be a terrible idea.

3You’re making unit testing more difficult than it needs to be. You suddenly rely on a third party providing your entities with IDs.

Say you’ve figured that a public ID setter is essentially a terrible sin, and you don’t want calling code to set the ID either. Your class would instead look something like this below.

Your ORM of choice is possibly still able to set the id field through reflection — you know, nothing is really safe from reflection…

But, how would you unit test this? The id field is set to 0 on instantiation. Instantiating more than one TerribleBook would leave you with identity collision, as now more than one TerribleBook has the same id, even tho your should represent two separate entities.

An example of domain generated IDs

The solution is honestly dead simple. Just have a look at the snippet below.

Let’s walk thru this code, as every change from the TerribleBook to FixedBook might not be obvious to everyone.

We make the constructor private and instantiate new objects using the static factory method. This allows us to abstract the instantiation logic from the caller and even provides us the opportunity to use polymorphism — we might want to return a Null Object instead of throwing.

Notice we’re still taking the id as a constructor parameter. But we are in charge of generating and providing the id (on line 18). Not the database.

The entity id datatype is changed from int to string — simply to allow the possibility to use something that is meaningful to the business. Do however watch out for performance issues and the consequences of using strings as IDs.

The Guid.NewGuid().ToString("D") just ensures we’ll get a hyphen formatted GUID. I like using GUIDs, but you’re free to build your own ids which ever way makes sense to your business and application needs.

UPDATE

Please note that I’m not talking about what to use as primary key…

Also, I make no claim my solution is without trade-offs.. Better entity design traded with potentially worse performance. I know that’s something DBAs will lose their minds over, but so be it.

You’ll have to make your own decisions about what’s best in your specific scenario.

Resources for the curious
--------------------------
When and where to determine the ID of en entity by Matthias Noback
CQS versus server generated IDs by Mark Seemann
Why Auto Increment Is A Terrible Idea by Clément Delafargue
UUID or GUID as Primary Keys? Be Careful! by Tom
SQL Server: Natural Key Versus Surrogate Key by Gregory A. Larsen

Nicklas Millard is a software development engineer in one of the fastest-growing banks, building mission-critical financial services infrastructure.

Previously, he was a Big4 Senior Tech Consultant developing software for commercial clients and government institutions.

New YouTube Channel (@Nicklas Millard)

Connect on LinkedIn

Programming
Software Development
Software Engineering
Database
Web Development
Recommended from ReadMedium