Understanding the Difference Between Entities and Value Objects
Understanding the Difference Between Entities and Value Objects in Domain Modelling
When designing software using Domain-Driven Design (DDD), one of the first decisions you’ll make is whether a concept in your model should be an Entity or a Value Object.
This distinction is crucial — it shapes how you design, persist, and reason about your data.
Let’s break it down using examples from our ongoing project, GoProcure, an enterprise-grade procurement system we’re building on this #CodeTrip journey.
What Is an Entity?
An Entity is an object that:
-
Has a unique identity (e.g., an
Idor unique identifier) -
Can change over time. (Muatable)
-
Is distinguished by its identity, not its attributes
Even if two entities have the same data, they are not the same if their identities differ.
Example from GoProcure:
Vendor and PurchaseOrder are Entities.
-
A
Vendormight change their company name or address, but it’s still the same vendor. -
A
PurchaseOrdermight have items added or removed, but it remains the same order as long as the PO number (or ID) remains constant.
Here, Vendor is an Entity because it has a unique Id and lifecycle.
However, the Address inside it is a Value Object — let’s talk about that next.
What Is a Value Object?
A Value Object:
-
Has no unique identity
-
Is defined only by its attributes
-
Is immutable — if something changes, you replace it entirely with a new instance
Two Value Objects are considered equal if all their property values are the same.
Example from GoProcure:
Address, Money, or DateRange can be modeled as Value Objects.
If a Vendor’s address changes, we don’t “edit” the Address; we assign a new one.
The old Address simply ceases to exist.
The same logic applies to Money. If you have Money(100, "USD"), it’s interchangeable with any other instance having the same amount and currency — it has no identity.
Address as a Value Object vs Address as an Entity
This is where many developers get confused.
✅ Address as a Value Object:
Use this when Address is only an attribute of another entity — for example, a Vendor’s address or a DeliveryLocation field in a Purchase Order.
Here, you don’t care about tracking the Address separately — you just need its data.
✅ Address as an Entity:
Make it an Entity when Address itself has identity or lifecycle — for example:
-
A logistics system where addresses are verified, reused, or updated by many users
-
A shared “AddressBook” where multiple Vendors or Customers link to the same address record
In that case, Address might look like this:
Key Differences at a Glance
| Feature | Entity | Value Object |
|---|---|---|
| Identity | Has a unique ID | No ID — defined by values |
| Mutability | Mutable (state can change) | Immutable (replace when changed) |
| Equality | Based on ID | Based on all attributes |
| Lifecycle | Tracked over time | Created and destroyed as needed |
| Example (GoProcure) | Vendor, PurchaseOrder, PurchaseRequest |
Address, Money, DateRange |
Why This Matters
Getting this distinction right ensures:
-
Cleaner domain models
-
Simpler persistence logic
-
Reduced duplication
-
Better performance (since Value Objects can often be embedded or cached easily)
It also improves how your ORM (like Entity Framework or JPA) maps data.
In EF, for example, you can treat Value Objects as owned types, embedded within their parent entities — reducing the need for extra tables.
Summary
In DDD:
-
Model Entities when identity and lifecycle matter.
-
Model Value Objects when you just need a reusable, immutable description of something.
For GoProcure:
-
Vendor,Item,PurchaseOrder, andApproval→ Entities -
Address,Money, andDateRange→ Value Objects
In the next post, we’ll explore Aggregation vs Composition vs Association — what each means, when to use them, and how they impact database design and cascading behavior in Entity Framework and JPA.
