MapStruct

guguli

Bekanntes Mitglied
Hallo zusammen,

ich habe eine Service class, da wird vom DTO aufs DomainModel gemappt.

An dieser Stelle möchte ich gerne das Framework Mapstruct anwenden, um MappingKlassen aufgrund von Annotations zu generieren.

Eine Service-class wieht wie folgt aus:

Code:
   /**
    * Uebernimmt die Werte aus dem uebermittelten DTO in das Domain-Objekt.
    *
    * @param dto
    * @param kapitalertragsteuer
    */
   private void dtoToDomain(final Kapitalertraege2013DTO dto, final KapitalertragsteuerEStGBase kapitalertragsteuer) {
       AbstractKapitalertraegeBase ertraege = kapitalertragsteuer.getKapitalertraege();

       if (!(ertraege instanceof Kapitalertraege2012)) {
           throw new IllegalArgumentException("Falsche Kapitalertragsteuer Implementierung [" + ertraege.getClass().getName()
                   + "]");
       }

       Kapitalertraege2012 ertraege2012 = (Kapitalertraege2012) ertraege;

       new SteuerabzugP43Abs1S1Nr1EStGService().uebernehme(dto, ertraege2012);
       new SteuerabzugP43Abs1S1Nr1aEStGService().uebernehme(dto, ertraege2012);
       new SteuerabzugP43Abs1S1Nr1und2bis4und7aEStGService().uebernehme(dto, ertraege2012);
       new SteuerabzugP43aAbs1S1Nr2EStGService().uebernehme(dto, ertraege2012);
       new SummenSteuerabzugUndErstattungService().uebernehme(dto, ertraege2012);
       new ErstattungP44aAbs6EStGService().uebernehme(dto, ertraege2012);

    
       BeschlussvorlageType beschlussvorlage = dto.getBeschlussvorlageType();
       if (beschlussvorlage != null) {
           ((Beschlussvorlage) ertraege).setBeschlussvorlage(beschlussvorlage.getBooleanWert());
       }

       if (LOGGER.isTraceEnabled()) {
           LOGGER.trace("## dtoToDomain #######");
           LOGGER.trace("dto: " + dto);
           LOGGER.trace("######################");
           LOGGER.trace("domain: " + ertraege);
           LOGGER.trace("######################");
       }
   }

kann einer mir einen Tipp geben?
Danke
 

mrBrown

Super-Moderator
Mitarbeiter
In dem Code findet kein Mappibg zwischen zwei Klassen statt, da werden sinnvolle Tipps schwierig.

Die MapStruct-Docu ist aber auch sehr Beispielreich, da sollte man eigentlich genug finden...


(Wenn du schon dabei bist, dieses LoggingMonster sollte auch mal refactored werden :p)
 

MoxxiManagarm

Top Contributor
Mir gefällt SteuerabzugP43Abs1S1Nr1und2bis4und7aEStGService - da sehe sogar ich sofort, worum es geht: Steuerabzug nach § 43 Abs. 1 Satz 1 Nr 1., 2. bis 4. sowie 7a EStG; Nr. 1 a) ist nicht dabei.
Ich hoffe du hast dein bestes Pokerface aufgelegt als du das geschrieben hattest :D

Ich persönlich bin ja ein totaler Fan von Kapitalertraege2012. Eine innovative Methode für jedes Jahr ein Auftragspensum sicherzustellen.;)
 

MoxxiManagarm

Top Contributor
Ich hätte lieber den Code nicht so posten sollen :(....naja
Ach quatsch, nein Code posten ist eigentlich immer wichtig. Ein Spaß muss auch mal sein..

Du hast aber eigentlich auch keine Frage zu deinem Post gestellt. Die Bitte nach einem Tipp ist sehr weitläufig. Hast du denn einen Fehler? Funktioniert irgendwas nicht?

Mir fällt nur auf, dass du hier zwar neue Klassen erstellst, aber du machst mit denen ja gar nichts...

Java:
new SteuerabzugP43Abs1S1Nr1EStGService().uebernehme(dto, ertraege2012);
       new SteuerabzugP43Abs1S1Nr1aEStGService().uebernehme(dto, ertraege2012);
       new SteuerabzugP43Abs1S1Nr1und2bis4und7aEStGService().uebernehme(dto, ertraege2012);
       new SteuerabzugP43aAbs1S1Nr2EStGService().uebernehme(dto, ertraege2012);
       new SummenSteuerabzugUndErstattungService().uebernehme(dto, ertraege2012);
       new ErstattungP44aAbs6EStGService().uebernehme(dto, ertraege2012);

Edit: Vergiss was ich gesagt habe, vermutlich veränderst du ertraege2012 innerhalb dieser Methoden. Das wird beim Lesen so aber nicht klar. Schöner wäre es, wenn ertraege2012 ein Rückgabewert wäre oder so.
 

guguli

Bekanntes Mitglied
@MoxxiManagarm Ich meinte den Code posten aber verändert.

Genau ich erzuge ein Objekt der klassen, wie aufgelistet, und rufe deren Metode auf. Die Methode uebernehme(dto, ertraege2012) macht eigentlich nicht viel:

Code:
public void uebernehme(final Zahl from, final Zah to) {
       if (to != null && from != null) {
           to.setSteuerErtrag(from.getSteuerErtrag());
           to.setSteuersoli(from.getSteuerSoli());
           to.setSteuerSteuer(from.getSteuerSteuer());
       }
   }

die Klasse Zahl ist ein Interface.
und hat zwei Implementierungen:
ein Mal "AbstractDTOBase" und einmal "AbstraktBase"

Ich möchte wissen wie ich MapStruct hier anstelle diese Art der Implementierung anwenden kann, bzw. ob das mit mapStruct überhaupt sinn macht.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich möchte wissen wie ich MapStruct hier anstelle diese Art der Implementierung anwenden kann, bzw. ob das mit mapStruct überhaupt sinn macht.
Ja, kannst du.

Die Frage ist nur, wie sinnvoll das ist. Wenn ich den Code richtig interpretiere, würdest du einfach sowas wie SteuerabzugP43Abs1S1Nr1aEStGService mit MapStruct ersetzen wollen?
 

guguli

Bekanntes Mitglied
Ja, kannst du.
Die Frage ist nur, wie sinnvoll das ist. Wenn ich den Code richtig interpretiere, würdest du einfach sowas wie SteuerabzugP43Abs1S1Nr1aEStGService mit MapStruct ersetzen wollen?

joa,
aber wie geht das? müsste ich dann eine Interface klasse implementieren "Mapper" und eine "MapperImpl".
in Mapper soll dann die methode uebernehme(dto, ertraege2012) declariert werden und in MapperImpl implementiert?

Oder wie soll das denn gehen?
 

mrBrown

Super-Moderator
Mitarbeiter
Du willst also den Code, der aktuell auf mehrere, spezifische Klassen verteilt ist, in eine einzige auto-generierte Implementierung stopfen?
 

mrBrown

Super-Moderator
Mitarbeiter
Naja alle diese Klassen mappen aber von "dto" nach "ertraege2012"... Also warum nicht?
Kommt drauf an, was die Services so machen :p

Wenn die alle nur Getter und Setter mit jeweils gleichen Feldern aufrufen würde ich das auch mit MapStruct umsetzen (dann hat der, der das fabriziert hat, aber auch was hinter die Ohren verdient...)

Wenn da aber mehr hinter steckt, würde ich das eher auf anderem Weg Refactoren (und mich generell fragen, warum jemand ohne passenden Wissensstand sowas machen soll...)
 

guguli

Bekanntes Mitglied
Also das hier ist nicht mein Code, ehrlich gesagt, ich kenn mich auch in dem System nicht so gut aus, ich habe nur die Aufgabe bekommen hierdrauf MapStruct anzuwenden. Ich weiss, dass das voll kompliziert gemacht wurde abe rnaja ist halt so und ich kann da nichts dran ändern.

Also um grob die Klassen Hierarchie zu erklären:
Es gibt Einen Service "KapitalertraegeService2013", da wird eine Override Methode "gebe" implementiert, da drin wird die Methode "dtoToDomain" aufgerufen. in dieser Methode werden dann das Objekt weiteren Services wie "SteuerabzugP43Abs1S1Nr1EStGService" erstellt, um die Methode "uebernehme" in diesen Services aufzurufen. Was diese methode tut habe ich ja vorhin schon gepostet.
Es gibt für jeden diese Services (Der Type der Übergabeparametern der Methode "uebernehme") eine Interface, welche die Setter und getter methoden, die in "uebernehme" Methode benutzt werden, deklariert. Diese Interfaces haben zwei Implementierungen. ein Mal "AbstractBase" und ein Mal "AbstractDTOBase".
Die Kindklasse der "AbstractDTOBase" wird als type einer der Übergabeparameter von der Methode "dtoToDomain" benutzt. und der type des anderen Übergabeparameter der methode "dtoToDomain" ist vom Type einer anderen Object "Model".

Also Wie ihr seht das ist schon kompliziert aber diese Services mahen eigentlich nichts anderes als den Wert zu erstzen.

Also MapStruct würde schon helfen das ganze zu optimieren aber ich weiss nicht so ganz wo ich anfagen soll usw.
ich habe mir auch die Docu von MapStruct angeschaut aber irgendwie kann ich das Prinzip nicht bei mir anwenden, bzw. ich weiss den Anfang nicht.

Danke für eure Hilfe im vorraus.
 

mihe7

Top Contributor
Ich kenne MapStruct nicht, und habe das mal kurz überflogen. Wenn ich es richtig sehe, würdest Du im Grundsatz ein
Java:
@Mapper 
public interface ZahlMapper {
    void uebernehme(@MappingTarget Zahl to, Zahl from);
}
schreiben. Dann kannst Du z. B.
Java:
Mappers.getMapper(ZahlMapper.class).uebernehme(to, from);
aufrufen.

Ich würde allerdings erst einmal schauen, ob man nicht eher auf DTOs verzichten kann.
 

Ähnliche Java Themen

Neue Themen


Oben