2

After reading the book; I understood the following:

1) Entities should implement equality and compare by ID. 2) Value Objects should implement equality and compare by all properties in the class.

I still believe that my understanding of point two is correct. However, I am confused about point one because of the following:

1) This blogger talks about creating an entity base class, which all entities inherit from: http://enterprisecraftsmanship.com/2014/11/08/domain-object-base-class/. Therefore all entities implement equality by ID because the equality comparisons are defined in the base class.

2) Most of the entity classes here have IDs: https://github.com/nhibernate/nhibernate-core/tree/master/src/NHibernate.DomainModel/Northwind/Entities

3) This question seems to suggest having an ID attribute: ID properties on Domain objects in DDD

4) This question points to a YouTube video (point one) where it is argued that entities should not have IDs.

Points 1-4 above seem to suggest either: 1) use a database ID; 2) use another ID that is not the database ID; 3) Use no ID.

I am trying to decide whether:

1) Have an entity superclass.

or 2) Have an ID (from database) in every entity.

or 3) Introduce an identifier (not database id) that identifies domain objects.

I am trying to completely isolate the domain model (I also have a data model).

  • Which one are you leaning towards and why? – Bernard Feb 7 '18 at 16:32
  • 3
    The blog post you linked to in point 1 was mentioned on this site recently and was received with a healthy and appropriate amount of scepticism. I believe the issue was specifically about his statement "you need to create the Id property in every single entity, which itself is a heavy violation of the DRY principle.". I wouldn't get too hung up on anything he says. Anyone can put up a blog and call themselves a craftsman. On a separate note, please check out my artisanal beers blog. – MetaFight Feb 7 '18 at 16:36
  • @MetaFight, could you provide a link to your blog? Which option would you go with i.e. 1, 2 or 3.? – w0051977 Feb 7 '18 at 16:53
  • @Bernard, I am leaned towards having no ID at all. My domain model is isolated so I don't believe it is needed. However, I don't want to discover that I do actually need it at some point in the future. – w0051977 Feb 7 '18 at 19:57
7

By definition, entities have an identity.

This fact, by itself, does not imply that you must have an Id property on your entity objects. If you never need to reference or compare the entity outside of your aggregate, there is not really a need for it.

Usually however, it makes sense for every entity to have an Id. Where does the Id come from? Unless you have a specific reason to do otherwise, I would prefer to have the application create the Id, not the database. You can use UUIDs (Guid in C#) or some custom IdGenerator. The fact that the database may use the Id value as a key is purely coincidental as far as your domain model is concerned.

This leaves the question of the Entity base class. There are a few reasons why you might not want to have one:

  • Entity is not a domain concept, so having your domain objects depend on it is not ideal.

    You might argue that Id is not a domain concept, either. Practical reasons for introducing it aside, I would argue that identity is an implicit domain concern - otherwise you could just use value objects.

  • The Entity will have very little functionality. Inheriting from it just to have an Id property, and possibly a very stable one-line (this.Id == other.Id) equality check seems like overkill.

That being said, I think it's very unlikely you'll run into problems due to the Entity base class. So if it helps you to focus on the domain logic (e.g. by not allowing you to forget to override Equals, in case this is how you intend to implement the equality check), by all means go for it.

  • How would the ID by generated? Guid.newid is used to generate the ID for the database in the Infrastructure layer. However, it seems not right to pass this ID to the domain layer. – w0051977 Feb 7 '18 at 19:59
  • @w0051977 no, the DB has nothing to do with the Id conceptually - though it will likely use the Id. Whatever is creating your entities (constructor/factory) should usually create the Id. To the database, it's just a happy coincident that there is an Id field that might be used as a key. – doubleYou Feb 7 '18 at 20:24
  • Thanks. Are you saying that the ID in the Infrastructure layer (Guid.NewID) would be different to the ID in the Domain Layer? – w0051977 Feb 7 '18 at 20:27
  • No the DB should use the entity's Id value, not create a second Id. But the database doesn't control the Id, it just uses it (as may other components of the system). Basically you move Guid.NewId() to your constructor/factory. – doubleYou Feb 7 '18 at 20:31
  • Thanks. I think you are saying "tell don't ask". That is how my infrastructure works i.e. the data object is created in memory with an ID and then persisted. However, if the Domain Model is used, then should the ID be passed to the domain model? – w0051977 Feb 7 '18 at 20:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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