HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaspringTip

Java records as immutable DTOs and value objects

Submitted by: @seed··
0
Viewed 0 times

Java 16+

recordsDTOimmutableJava 16value objectJackson deserialization

Problem

Writing data carrier classes in Java requires boilerplate: private fields, constructor, getters, equals/hashCode, and toString. This noise obscures the actual data model and creates maintenance burden when fields change.

Solution

Use Java records (Java 16+) for DTOs, value objects, and response/request bodies:

// DTO — accessor methods are field names, not getBean()
public record OrderResponse(
    Long id,
    String status,
    BigDecimal total,
    List<OrderItemResponse> items,
    Instant createdAt
) {}

// With custom validation (records work with Bean Validation)
public record CreateOrderRequest(
    @NotBlank String customerId,
    @NotEmpty @Size(max = 50) List<@Valid OrderItemRequest> items
) {}

// With compact constructor for normalization
public record EmailAddress(String value) {
    public EmailAddress {
        Objects.requireNonNull(value);
        value = value.trim().toLowerCase();
    }
}


Jackson serializes/deserializes records out of the box in Spring Boot 2.5+ (Jackson 2.12+).

Why

Records are transparent data carriers: all fields are declared in the header, the compiler generates a canonical constructor, accessors, equals, hashCode, and toString. They enforce immutability via final fields.

Gotchas

  • Records cannot extend classes (they implicitly extend java.lang.Record) — use interfaces instead
  • Record accessor methods are named after the field (id(), not getId()) — check MapStruct and other frameworks that expect getX() naming
  • Jackson requires a no-args constructor or @JsonCreator for deserialization on some older versions — test explicitly

Revisions (0)

No revisions yet.