GEDOPLAN
JavaJakarta EE (Java EE)Java SEModellierung

Mapstruct mit ValueObjects

JavaJakarta EE (Java EE)Java SEModellierung
mapstruct vo 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

ng20 png
Angular, Webprogrammierung

Angular 20

Angular 20 steht in den Startlöchern. Ein vermeintlich kleines Update steht an, in dem es leider die Signal-Based Formulare nicht…
IT-Training - GEDOPLAN
Webprogrammierung

Angular 5 Konverter

Ein sehr häufig vorkommendes Szenario bei der Arbeit mit Fomularen ist die Umwandlung von Werten, also die Konvertierung zwischen Formular-…

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!