0

I am following this book on Spring Boot with domain driven design where the author models a Cargo entity which has a bunch of attributes. The two attributes in question are the numerical key and a business key (bookingId). The Cargo entity is as below

**Cargo.java**


package whatever;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Entity
@Getter @Setter
public class Cargo {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Embedded
    private BookingId bookingId; // Business Identifier
}

**BookingId.java**

package whatever;

import lombok.Getter;
import lombok.Setter;

import javax.persistence.Column;
import javax.persistence.Embeddable;

@Embeddable
@Getter @Setter
public class BookingId {
    @Column(name="booking_id")
    private String bookingId;
}

As you can see, the author has modelled the business key as an embedded object. What are the benefits of embedding an attribute inside another object? Why don't we just have a String variable called bookingId in Cargo class and enforce a uniqueness constraint on it?

Marco Polo
  • 113
  • 1
  • 6
  • Possible duplicate of https://stackoverflow.com/questions/35174981/when-to-use-embedded-and-embeddable – rt.jar Aug 24 '20 at 13:40
  • Does this answer your question? [When to use @Embedded and @Embeddable?](https://stackoverflow.com/questions/35174981/when-to-use-embedded-and-embeddable) – rt.jar Aug 24 '20 at 13:40
  • @rt.jar It partially does. I understood that when you want to "group" certain attributes (like audit data) which occur in a lot of your application entities, then you'd use embedded objects. But in my case, the bookingId string which is a business key and just a string is also represented as a separate object. I have accepted an answer which I thought was more suitable for my question. Thanks! :) – Marco Polo Aug 24 '20 at 13:59

1 Answers1

3

Why don't we just have a String variable called bookingId in Cargo class and enforce a uniqueness constraint on it?

Two main reasons:

Using a specific type, rather than a general-purpose primitive like String, allows the compiler to distinguish booking identifiers from other kinds of strings, reducing the changes that you inadvertently pass a booking id where a location identifier is required.

Also, defining a class (like BookingId) gives you logical separation of "code that needs to know the underlying data structure" from "code that doesn't. In other words, you benefit from the cohesion of having your booking identifier data structure queries all in one place.

(The second of these tends to be less important for "identifiers" than for other value types in your model. In many cases, identifiers are semantically opaque - about the only real thing you can do to them is compare them to one another.)

Modeling information with explicit types also allows you to reduce the space of operations, eliminating methods that don't make any sense. For instance, taking a substring of a booking id probably doesn't achieve anything useful, so you simplify the api by reducing it to those semantics that make sense in your domain model.

You'll see similar concerns with collections; Lists and Maps tend to have a broad interface so that they support many possible applications, but the shipping domain isn't about lists and maps, its about Itineraries. The fact that the standard library happens to have a convenient data structure to use is an accident of implementation, not a part of the business that you are trying to model.

Does it matter? Ultimately, the machine really doesn't care about code design - but the next human that comes along to make a change will be impacted by the design quite a bit. Part of the motivation of the common DDD patterns is that the code is designed so that you, the programmer, can concentrate on the task at hand (see also the separation of "domain code" from "persistence code", and the introduction of the life cycle patterns in chapter 6 of Evans 2003).

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91