Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Domain Entities and Value Objects in DDD

Tech May 7 3

Entities

An entity is a domain object that carries business meening and encapsulates multiple attributes and behaviors relevant to a specific business context. During domain modeling, entities are identified based on their role within business scenarios. These entities are then grouped into aggregates according to their relationships.

The defining characteristic of an entity is its unique identifier, which remains constant throughout the application lifecycle, regardless of changes in state or process flow. In domain models, entities are typically represented as Data Objects (DOs).

For example, in a personnel attendance subdomain, an employee who completes a full attendance cycle through clock-in and clock-out actions is considered an entity. Each employee has a unique ID (such as an employee number), which does not change even when they travel for work. This entity also includes methods like clockIn() and clockOut(), forming a rich model.

/**
 * Employee entity
 */
public class Employee {
    private String id;
    private String name;
    private Address address;
    
    public void clockIn() {
        // Implementation
    }
    
    public void clockOut() {
        // Implementation
    }
}

Value Objects

In the previous example, an employee's address consists of province, city, and street components. These can be abstracted into a separate Address class, representing a value object—a collection of related attributes that form a conceptual whole.

Value objects have no identity of their own; they are immutable and represent a concept rather than an entity.

/**
 * Address value object
 */
public class Address {
    private String province;
    private String city;
    private String street;
}

Relationship Between Entities and Value Objects

Both entities and value objects serve as foundational elements in microservices and implement core business logic.

Entities usually embody business concepts, containing both data and behavior. They are responsible for business operations and maintain state.

Value objects, in contrast, consist of data only, typically initialized once and never modified afterward. They lack business logic and often act as components within entities.

When a value object contains only one attribute, it can be directly embedded in the entity. If it groups several attributes, it should be modeled as a separate value object class. Value objects do not possess identifiers and are referenced entirely by the entity.

Database Representation

Entities

Mapping a domain entity (DO) to a database model may result in zero, one, or multiple persistent objects (POs). Usually, there is a one-to-one mapping between DO and PO. However, if a DO exists only in memory, persistence might be unnecessary. When two entities merge into one (e.g., user and role into permission), a single DO maps to multiple POs. Conversely, when two DOs are merged into one table, their coresponding POs may need to be split, resulting in a many-to-one relationship.

Value Objects

Value objects are commonly stored using denormalization techniques. Their properties are serialized into JSON and stored alongside the entity’s fields in a single database table.

Consider the following approaches for storing an employee and their address:

  1. Flatten all address fields in to the employee table — this loses semantic clarity and integrity.
  2. Create separate tables for employee and address — introduces unnecessary complexity.
  3. Embed the value object as a JSON string in the employee table — preserves semantics and reduces schema complexity.

Modern databases support JSON-based CRUD operations, making approach #3 feasible and common. However, excessive use of value objects can lead to bloated entities with unrelated attributes.

Value objects are immutable, ensuring thread safety in concurrent environments. Because they cannot be changed, they can safely be shared across multiple entities. Therefore, in high-concurrency systems, favoring value objects over entities helps maintain consistency and performance.

Another benefit of value objects is their ability to capture snapshots of data at critical moments. For instance, when an order is created, the associated user and address information can be embedded in JSON form into the order record. This avoids repeated lookups of user data during order processing and decouples the user and order aggregates. It also preserves historical context by retaining a snapshot of the data at the time of creation.

Anemic vs. Rich Models

An anemic model treats domain objects as simple data containers, often seen in Spring beans. For example, a principal in education would only store age, rank, and years of service without implementing any behavior-related methods.

A rich model, however, combines data and behavior within the same object. An entity in a rich model not only stores data but also defines methods that reflect real-world actions.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.