Java Omnibus
OOAD & Architecture / Domain-Driven Design / Entities and Value Objects
DDD Entities Value Objects Java
Tactical DDD

Entities and value objects matter because identity and meaning are not the same thing, and a healthy model treats them differently.

DDD sharpens one of the most useful modeling distinctions in object-oriented design: some things matter because they have identity over time, while others matter only because of what they are. Orders are entities. Money and addresses are often value objects. The distinction changes equality, lifecycle, and behavior design.

Why This Topic Matters

Why it matters in real Java systems

If a shipping address is treated like an entity when it should be a value object, the model becomes awkward. If an order is treated like just a value bag when it has identity and lifecycle, the model becomes brittle. This distinction affects almost every important modeling decision.

Core Explanation

The main design idea

An entity is defined by continuity and identity. A value object is defined by attributes and meaning. Value objects are often immutable and easier to reason about. Entities usually own lifecycle and state transitions over time.

DDD makes this distinction especially useful because rich domain models often improve when more concepts become value objects and fewer concepts are treated as generic entities by default.

Concept Breakdown

Key ideas to keep in mind

Concept

Entity

Identity over time matters more than full structural equality.

Concept

Value object

Meaning comes from attributes, and immutability often improves safety.

Concept

Model payoff

The distinction clarifies invariants, equality, and ownership.

Example distinction

Example distinction

Example: an Order remains the same business object even as status changes. A Money amount or ShippingAddress is usually best treated as a value object because its meaning comes from the values it contains.
Java Example

Java example in the Order Management domain

Java example: entity and value object together
package org.javaomnibus.ecommerce.domain;

public record Money(java.math.BigDecimal amount, String currency) {}

public final class Order {
    private final OrderId id;
    private Money total;

    public Order(OrderId id, Money total) {
        this.id = id;
        this.total = total;
    }

    public OrderId id() {
        return id;
    }
}
Code Walkthrough

Step by step

  1. Money is a value object because its meaning comes from its amount and currency.
  2. Order is an entity because its identity persists even as its state changes.
  3. That distinction changes how equality and behavior are designed.
  4. DDD becomes clearer when this decision is intentional rather than accidental.
Real-World Usage

Where this helps in practice

  • Modeling money, addresses, ranges, and policy parameters as value objects
  • Keeping orders, payments, and shipments as lifecycle-bearing entities
  • Reducing primitive obsession and improving model meaning
Trade-Offs

Trade-offs and when to be careful

  • Value objects improve clarity, but inventing too many tiny ones without clear meaning can hurt readability.
  • Entities need discipline so identity does not become an excuse for weak modeling.
Common Mistakes

Frequent mistakes to watch for

  • Treating every domain concept as an entity by default
  • Using primitive types where a value object would express intent better
  • Making value objects mutable without a clear reason
  • Confusing database identifiers with the whole meaning of an entity
Related Pages

Related concepts


What To Read Next