Entity vs Value Object: the ultimate list of differences

By Vladimir Khorikov

The topic described in this article is a part of my Domain-Driven Design in Practice Pluralsight course.

I wrote about entities and value objects some time ago. In this post, I’d like to talk about differences between Entity vs Value Object in more detail.

I know, the topic isn’t new and there are a lot of articles on the Internet discussing it already. Nevertheless, I didn’t find any with an exhaustive, comprehensive description, so I decided to create my own.

Entity vs Value Object: types of equality

To define the differences between entities and value objects, we need to introduce three types of equality which come into play when we need to compare objects to each other.

Reference equality means that two objects are deemed to be equal if they reference the same address in the memory:

Entity vs Value Object: Reference equality

Reference equality

Here’s how we can check that in code:

object object1 = new object();

object object2 = object1;

bool areEqual = object.ReferenceEquals(object1, object2); // returns true

Identifier equality implies a class has an id field. Two instances of such a class would be equal if they have the same identifiers:

Entity vs Value Object: Identifier equality

Identifier equality

And finally, with structural equality, we consider two objects equal if all of their members match:

Entity vs Value Object: Structural equality

Structural equality

The main difference between entities and value objects lies in the way we compare their instances to each other. The concept of identifier equality refers to entities, whereas the concept of structural equality – to value objects. In other words, entities possess inherent identity while value objects don’t.

In practice it means that value objects don’t have an identifier field and if two value objects have the same set of attributes we can treat them interchangeably. At the same time, if data in two entity instances is the same (except for the Id property), we don’t deem them as equivalent.

You can think of it in a similar way you would think of two people bearing the same name. You don’t treat them as the same person because of that. Both of the people have their own inherent identity. Yet, if a person has a 1 dollar bill, they don’t care if this physical piece of paper is the same as they had yesterday. Until it’s still 1 dollar, they are fine with replacing this note with another one. The concept of money in such case would be a value object.

Entity vs Value Object: lifespan

Another distinction between the two notions is the lifespan of their instances. Entities live in continuum, so to speak. They have a history (even if we don’t store it) of what happened to them and how they changed during their lifetime.

Value objects, at the same time, have a zero lifespan. We create and destroy them with ease. That’s a corollary of being interchangeable. If this 1 dollar bill is the same as another one, why bother? We can just replace the existing object with the one we just instantiated and forget about it altogether.

A guideline that flows from this distinction is that value objects cannot live by their own, they should always belong to one or several entities. The data a value object represents has a meaning only in the context of an entity it refers to. In the example above with people and money, the question “How much money?” doesn’t make any sense because it doesn’t convey proper context. At the same time, questions “How much money Peter has?” or “How much money all our users possess?” are perfectly valid.

Another corollary here is that we don’t store value objects separately. The only way for us to persist a value object is to attach it to an entity (more about it in a minute).

Entity vs Value Object: immutability

The next difference is immutability. Value objects should be immutable in a sense that if we need to change such an object, we construct a new instance based on the existing object rather than changing it. On the contrary, entities are almost always mutable.

The question whether or not value objects should always be immutable is a subject of a dispute. Some programmers argue that this rule is not as strict as the previous one, and value objects can indeed be mutable in some cases. I used to adhere to this point of view as well.

Nowadays, I find the connection between immutability and the ability to replace a value object with another one is deeper that I thought. By mutating an instance of a value object, you assume it has its own life cycle. And that assumption, in turn, leads to a conclusion that the value object has its own inherent identity, which contradicts the definition of that DDD notion.

This simple mental exercise makes immutability an intrinsic part of Value Object. If we accept value objects have a zero lifetime, meaning that they are just snapshots of some state and nothing more, then we have to admit they are allowed to represent only a single variant of that state.

That leads us to the following rule of thumb: if you can’t make a value object immutable, then it is not a value object.

How to recognize a value object in your domain model?

It’s not always clear if a concept in your domain model is an entity or a value object. And unfortunately, there are no objective attributes you could use to get to know it. Whether or not a notion is a value object fully depends on the problem domain: a concept can be an entity in one domain model and a value object in another.

In the example above, we treat money interchangeably, which makes this concept a value object. At the same time, if we build a software for tracking cash flow in the entire country, we would need to treat every single bill separately to gather statistics for each of them. In this case, the notion of money would be an entity, although we would probably name it Note or Bill.

Despite the lack of objective traits, you can still employ some technique in order to attribute a concept to either entities or value objects. We discussed the notion of identity: if you can safely replace an instance of a class with another one which has the same set of attributes, that’s a good sign this concept is a value object.

A simpler version of that technique is to compare a value object to an integer. Do you really care if the integer 5 is the same 5 that you used in another method? Definitely not, all fives in your application are the same regardless of how they were instantiated. That makes an integer essentially a value object. Now, ask yourself, is this notion in your domain looks like integer? If the answer is yes, then it’s a value object.

How to store value objects in the database?

Let’s say we have two classes in our domain model: Person entity and Address value object:

// Entity

public class Person

{

    public int Id { get; set; }

    public string Name { get; set; }

    public Address Address { get; set; }

}

 

// Value Object

public class Address

{

    public string City { get; set; }

    public string ZipCode { get; set; }

}

How would the database structure look like in this case? One option that comes to mind is to create separate tables for each of them, like this:

Entity vs Value Object: Storing the value object in a separate table

Storing the value object in a separate table

Such design, albeit being perfectly valid from the database standpoint, has two major drawbacks. First of all, the Address table contains an identifier. It means that we will have to introduce a separate Id field in the Address value object to work with such table correctly. This, in turn, means we are providing the Address class with some identity. And that violates the definition of Value Object.

The other drawback is that with this solution, we can potentially detach value objects from entities. The Address value object can now live by its own because we are able to delete a Person row from the database without deleting the corresponding Address row. That would violate another rule which states that the lifetime of value objects should fully depend on the lifetime of their parent entities.

It turns out that the best solution is to inline the fields from the Address table into the Person table, like this:

Entity vs Value Object: Inlining the value object

Inlining the value object

This would solve all the problems I stated earlier: Address doesn’t have an identity anymore and its lifetime now fully depends on the lifetime of the Person entity.

This design also makes sense if you mentally replace the fields that regard to Address with a single integer as I suggested previously. Do you create a separate table for an integer? Of course not, you just inline that integer to the table you want it to be in. The same applies to the value objects. Don’t introduce separate tables for value objects, just inline them into the parent entity’s table.

Prefer value objects over entities

When it comes to working with entities and value objects, an important guideline comes into play: always prefer value objects over entities. Value objects are immutable and more lightweight than entities. Because of that, they are extremely easy to work with. Ideally, you should always put most of the business logic into value objects. Entities in this situation would act as wrappers upon them and represent more high-level functionality.

Also, it might be that a concept you saw as an entity at first essentially is a value object. For example, the Address class in your code base could be introduced as an entity initially. It may have its own Id field and a separate table in the database. After revisiting it, you might notice that in your domain, addresses don’t actually have their own inherent identity and can be used interchangeably. In this case, don’t hesitate to refactor your domain model and convert the entity into a value object.

Summary

Alright, I think I covered every aspect that regards to the topic of Entity vs Value Object. Let’s summarize it with the following:

  • Entities have their own intrinsic identity, value objects don’t.
  • The notion of identity equality refers to entities; the notion of structural equality refers to value objects; the notion of reference equality refers to both.
  • Entities have a history; value objects have a zero lifespan.
  • A value object should always belong to one or several entities, it can’t live by its own.
  • Value objects should be immutable; entities are almost always mutable.
  • To recognize a value object in your domain model, mentally replace it with an integer.
  • Value objects shouldn’t have their own tables in the database.
  • Always prefer value objects over entities in your domain model.

Related articles:





  • Hash

    Excellent article as always.

    One typo here “First of all, the money table contains an identifier”, I guess you meant “Address” table

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      You are right. Fixed that, thanks!

  • Dmitri

    Great insight!

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thank you!

  • Aleksandras

    Nice article and nice timing.:) I was googling/stackoverflowing about that just few days ago, since I had some concerns what approaches others are using for Entity vs Value Objects.

    Specifically I’m still not sure, and not enough convinced by your article, that Value Objects should be inlined into Entity table. At least not always, and not as rule of thumb. What if Value Object has more properties? What if there are much more Value Objects related to an Entity? At the end I feel it might end with a terrible DB design.

    Actually it’s more like persistence question how to store and where to store, while Domain Entities shouldn’t care about persistence at all. So separating such concerns (Domain and its’ persistence), maybe it’s not as bad to store Value Objects to separate tables?
    If you are trying to use relational DB for persistence – then you probably should care about DB design. If you feel it doesn’t feet your DDD approach – then maybe relational DB is not the best option? Another option would be to use relational DB, but store Value Object as serialized data (some kind a mix of relational and NoSQL). Of course it has it’s own drawbacks.

    Any additional thoughts about it? It would be good to hear something about it, and maybe some more alternatives/options/what-to-choose-when. 🙂

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thank you for your comment, you are raising good points. I’ll try to go through all of them now.

      Actually it’s more like persistence question how to store and where to store, while Domain Entities shouldn’t care about persistence at all.

      I agree, the domain layer shouldn’t care about how it is being persisted, but we, as programmers, should. The contradiction here is seeming: it’s our duty to provide proper separation of concerns and a good degree of domain model isolation but at the same time, we should see the bigger picture. We need to take into account such concerns as entities’ and value objects’ lifetimes and design our database accordingly. The entities and value objects themselves, of course, shouldn’t be aware of those concerns, that’s not part of their responsibility.

      What if Value Object has more properties? What if there are much more Value Objects related to an Entity? At the end I feel it might end with a terrible DB design.

      Lack of normalization by itself doesn’t mean a bad DB design; normalized table structure doesn’t automatically mean good design. I know what you are talking about, I myself was (and still is) into DB design a lot. It feels weird to see a database table growing in terms of the number of columns. The first impulse here is to normalize it, extract the “common parts” to a separate table. Nevertheless, I strongly believe such design decision doesn’t do any good with Value Objects (for the reasons I stated in the article).

      I find it easier to cope with this temptation by viewing the database as a bag of data, the sole purpose of which is to persist the domain model and provide some nice querying capabilities. As long as the domain model looks good (and value objects, in my opinion, do lead to better design), we should be fine. Another technique that helped me convince myself to always apply this approach is to view a value object as an inflated integer. We don’t create a separate table for every integer in our entities (although we could), neither should we do it for value objects.

      If you are trying to use relational DB for persistence – then you probably should care about DB design. If you feel it doesn’t feet your DDD approach – then maybe relational DB is not the best option? Another option would be to use relational DB, but store Value Object as serialized data (some kind a mix of relational and NoSQL).

      Sure, we should always be caring about DB design. My main point here is that normalized table structure != good DB design. In fact, I find it opposite in many cases (interesting coincidence, my next post is going to be on that topic).

      Regarding serialized data – I think it’s essentially the same thing as inlining the Value Object’s columns into the Entity’s table. The only benefit we have here is reducing the number of columns, and it comes at the price of damaging explicitness. And again, fewer columns != good DB design, so reducing the number of columns shouldn’t be a target by itself.

      maybe it’s not as bad to store Value Objects to separate tables?

      My view on that topic changed in the course of working on different domains. I used to think that sure, in some cases introducing a separate table for a value object doesn’t do any harm. Nowadays, I think that it’s more of a strong guideline. Today, I tend to always inline value objects into entities’ tables, and I think it makes the overall design (both DB and domain model) simpler and more expressive.

      • Aleksandras

        Thanks for a such detailed response. I fully agree with you, that normalized DB does not always automatically means it’s well designed. There is always a balance. Same thing as “clean code” (or “clean DB” with “enough number of columns”) – is quite abstract thing.

        I just read similar topics and was confused – while some guys are not so categorical and are saying there are at least more than one possible approaches to store Value Objects; others are saying that storing Value Objects as “DB entities” is not as bad, if you are using relational DB; then I saw your opposite point.

        However now I see your stronger points why you are advocating about this approach, and see quite clear reasons behind it.
        Looking forward to see your next post – about the topic you just spoiled.;)

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Glad you found it interesting 🙂

          Regarding other programmers not being so strict about this guideline: I think in most cases it boils down to the restrictions imposed by the ORM they use – Entity Framework. Its support for value objects is horrible, so it sometimes makes sense to just give up on that guideline and treat value objects the same way as entities – with their own DB tables.

          Here we had a similar discussion with Anders (scroll down to the comments section): http://enterprisecraftsmanship.com/2015/01/03/value-objects-explained/

  • David Raab

    I never have seen an application where it is not possible to save multiple addresses for a single person. In address books you usually also can save multiple phone numbers, credit card numbers and a lot of other stuff that you probably consider value object.

    And with your definition that creates a problem. If you inline all those in a relation database you cannot save multiple things. And i hope you are not saying that we should create columns “phone1”, “phone2”, “phone3”, …

    Strictly following your rules those then have to be entity objects, what also doesn’t make much sense for me.

    Actually, Entity object or value object has nothing todo with the relational model at all. You inline data when you have a 1:1 relation between data. Otherwise you extract data in its own table. And it doesn’t matter if something represents an entity or value. The relational model in general has nothing todo with entity/value.

    If you found that a problem that is a problem that only exists by the relational model. If you have entity/value objects and don’t use a relational storage and you for example use a NoSQL database (like a document-based database), none of your persistence problems really exists.

    And on the other hand. If you insist that the relational model and entity/value objects are close together somehow. Then why do you create two classes “Address” and “Person”? Why not also inline the Address fields into the Person class? If it makes sense to inline those data you would also already inline those data in the “Person” class. That you don’t do that is probably a reason why you also shouldn’t do it in the relational model.

    • syclee

      “Actually, Entity object or value object has nothing todo with the relational model at all. You inline data when you have a 1:1 relation between data. Otherwise you extract data in its own table. And it doesn’t matter if something represents an entity or value. The relational model in general has nothing todo with entity/value.”

      I’m trying to implement DDD in my work and I keep getting stumped and confused with this. For example, is an associative table a value object? Is it even meant to be introduced to the Domain Model, or is it purely a db level detail? If I don’t want to introduce this to the Domain Model, how can I query against it using NHibernate? Also an associative table entry has identiy, so that means it must be an entity? But its values are entirely dependent on the associating entities so it must be a value object. Maybe I shouldn’t have an associative table at all? But then I might pollute one of the domain objects with details it shouldn’t care about?

  • Michael G.

    Good article.
    I have a a question on how to treat Entities that lose their requirement for an identity for a time, but later on regains it.

    Suppose you have a PiggyBank that you and your friends each put some collectible coins in. Furthermore, as long as the coins are in the PiggyBank, noone cares which coin belongs to who, only the total is relevant. Finally, at some point, the PiggyBank will have to be opened, and the Coins given back to whomever put them in in the first place.

    At no point will it be possible to tell which coins are in the PiggyBank, except get a total sum of all the coins deposited. However, once it is opened, each Coin must be identifiable so it can be returned to the owner.

    How would you model such a scenario?

    Would you just keep a collection of Coin entities in the PiggyBank model, or is there some way to turn them into value objectswhile residing in the PiggyBank, but transform them into entities later?

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Interesting question. I don’t think that a concept can transition from being an Entity to a Value Object over time. Usually, you either care about its identity within a given bounded context or not.

      In the scenario you described, you either want to track each coin separately in order to return this exact coin to the owner, or you don’t – in this case it’s fine to return the owner an equivalent coin or several coins of equivalent value. I don’t see how you can stop keeping track of coins in the former scenario even when the coins reside in the PiggyBank. You’ll need to return them to the owner, and dropping their identity would lead to inability to do that.

      • Michael G.

        Thank you for the quick reply. It makes sense that dropping the identity would make the scenario impossible to implement.

  • Michael G.

    I mentioned this in another blog entry of yours, but it bears merit to mention it here as well:

    When working with any ORM that is capable of doing 1-to-1 mappings, it can be a valid approach to persist value objects in a separate table in the database. To do so, the identified (primary key) in the Address table would also be PersonID, which is also a foreign key from the Person table.

    By doing it that way, an Address cannot exist on its own in the database, and the Person table doesn’t grow out of proportion with 40+ columns/fields.

    Inlining is still viable. It just comes down to personal preference. I prefer to keep different concepts in different tables, and to keep the entity table as clean as possible.

    One added benefit of 1-to-1 mapping value objects is that it becomes much easier to refactor them for different versions of the same system, especially when there is a transition period, as you can store the new version in a different table altogethe, and not worry about having to change the structure of the old version.

    This does introduce a bit of overhead and duplication of data during the transitional period, but I find that to be a minor issue compared to the benefits.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Great summary! And great point about transition periods, having a separate table for value objects indeed makes database refactoring easier in scenarios with multiple client applications (or multiple versions of the same client application).

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      I must note, however, that this approach only works when you have a single entity containing the value object. If, for example, there’s also Organization with an Address property, you won’t be able to use the same Address table.

      • Michael G.

        Good point. In such a case I would opt for keeping two sets of
        addresses: One for private addresses, and one for organization addresses.

        Alternatively, and this is where the solution starts to become muddy, and not something I would recommend, you could make the primary key of the Address table include both PersonID and OrganizationID, with the possibility of either being NULL, but not both, with a constraint that ensures that only one of the foreign keys ever has a value.

        Not something I would recommend, but it is possible to do. Instead I would either inline them, or, as mentioned above, keep separate tables.

  • ScottC

    I’m probably missing the obvious, but I’m hoping someone can help me pull this together. My question is about the need to have separate value objects and entity objects. If value objects are inlined with their entity owners in the data layer, why not inline them in code as well and simply avoid having value objects?

  • yatko niglib

    I still find it difficult to differ between Value Object and Entity.
    For instance…

    IT-Book -> Entity … because it has an ID in form of an ISBN!
    1$ Dollarbill -> Value Object …but a 1$ Dollarbill also has kind of a manufacturing number, which i could consider as an ID!

    Am i right or wrong? I dont get this…

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Whether or not a concept is a value object depends on the context. 1 dollar bill can have a manufacturing number (which makes this bill unique) but you don’t necessarily care about it. It’s whether or not the use cases in your application involve distinguishing 1 dollar bills. If they do (like when you need to track the flow of all currency), then it’s an entity. If not (like when you just need to treat them as money), it’s a value object.

  • Marin Matenda

    Hi, how would you persist value object in a case when address is considered as a value object, but a person can have more then one address. A new table would be required, and would that make an address an entity ie. Are child lists of data always considered as entities?