GEDOPLAN
JavaJakarta EE (Java EE)Java SEModellierung

Mapstruct mit ValueObjects

JavaJakarta EE (Java EE)Java SEModellierung
rect4631 png

Mapstruct (https://mapstruct.org/) ist eine meiner liebsten Bibliotheken im Alltag. Erleichtert diese Bibliothek das Mapping zwischen Java Objekten (z.B. JPA Entities und DTOs) enorm. Ein Interface deklarieren. Methoden-Signatur schreiben. (oft schon) Fertig.

Sollten wir im Projekt ValueObjects einsetzen, also ein (Wrapper-) Objekte, die unveränderliche Werte darstellen, bedarf es nun immer händisches Eingreifen, um die konkreten Werte dieser ValueObjects in eine flache DTO Struktur zu bringen. Zumindest für die einfachen Fälle, mit nur einem Attribut, bietet es sich an einen generischen Mapper zu registrieren.

Vorab schauen wir uns die Ausgangslage an. Wir definieren ein Interface für unsere einfachen ValueObject-Typen und verwenden diesen, hier am Beispiel einer CustomerId:

public interface ValueObject<T> {
    T value();
}
    public record CustomerId(UUID value) implements ValueObject<UUID> {
    }

    public record Customer(CustomerId customerId, String name) {
    }

    public record CustomerDto(UUID customerId, String name) {
    }

Ziel ist es ja nun, ohne viel Aufwand, unser Mapping zu realisieren. Im Idealfall sieht das nun so aus:

@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA_CDI, uses =  ValueObjectMapper.class)
public abstract class DemoMapper {

    public abstract Customer mapToCustomer(CustomerDto dto);
    public abstract CustomerDto mapToDto(Customer customer);

}

In der ersten Zeile sehen wir bereits die Lösung. Wir inkludieren einen weiteren Mapper, der sich generischen um die Umwandlung unserer (zumindest einfachen) ValueObjects kümmert. Dieser könnten jetzt so aussehen.

@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA_CDI)
public abstract class ValueObjectMapper {

    public <T> T mapToValue(ValueObject<T> valueObject) {
        return Optional.ofNullable(valueObject)
                .map(ValueObject::value)
                .orElse(null);
    }

    public <V extends ValueObject<T>, T> V mapToObject(T value, @TargetType Class<V> valueObjectClass) {
        if (value == null) {
            return null;
        }
        try {
            Constructor<V> constructor = valueObjectClass.getDeclaredConstructor(value.getClass());
            constructor.setAccessible(true);
            return constructor.newInstance(value);
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Kein passender Konstruktor gefunden für " + valueObjectClass.getName(), e);
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException("Fehler beim Erzeugen der Instanz von " + valueObjectClass.getName(), e);
        }
    }
}

Damit lassen sich wieder unsere Modelle mappen, ohne dass wir übermäßig viel Mapping-Deklarationen hinzufügen müssen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Bitte füllen Sie dieses Feld aus.
Bitte füllen Sie dieses Feld aus.
Bitte gib eine gültige E-Mail-Adresse ein.
Sie müssen den Bedingungen zustimmen, um fortzufahren.

Autor

Diesen Artikel teilen

LinkedIn
Xing

Gibt es noch Fragen?

Fragen beantworten wir sehr gerne! Schreibe uns einfach per Kontaktformular.

Kurse

weitere Blogbeiträge

IT-Training - GEDOPLAN
Jakarta EE (Java EE)

Lifecycle-Events der CDI-Scopes

Beim Aktivieren und Deaktivieren von CDI-Scopes sendet der Container Events, die von der Anwendung bspw. zur Initialisierung genutzt werden können.…
ChatGPT Image 27. Juni 2025 12 04 17 png
Spring

Spring Boot Micrometer

In einem der letzten Beiträge (hier) haben wir bereits einen Blick auch Spring Boots Actuator Feature geworfen. Als kleine Ergänzung…

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!

Work Life Balance. Jobs bei Gedoplan

We are looking for you!

Lust bei GEDOPLAN mitzuarbeiten? Wir suchen immer Verstärkung – egal ob Entwickler, Dozent, Trainerberater oder für unser IT-Marketing! Schau doch einfach mal auf unsere Jobseiten! Wir freuen uns auf Dich!