2016-05-16 3 views
1

Ich verwende MapStruct, um von einer JPA-Entität zu einem POJO-DTO in einer Spring-App mit Abhängigkeitsinjektion zu mappen.Wie verwendet man die Decorated-Methode in Mapstruct Collection Mapper?

Ich habe eine zusätzliche Verarbeitung des DTO zu einer Methode in einem Decorator as specified in the doc hinzugefügt.

Es funktioniert gut für die Zuordnung einer einzelnen Entität. Aber ich habe auch eine Zuordnung für eine Sammlung (Menge) dieser Entitäten und die Methode wird automatisch aufgerufen, wenn eine Sammlung dieser Entitäten in einer Beziehung gefunden wird.

Die generierte Auflistungszuordnungsmethode verwendet jedoch nicht die Decorated-Methode zum Zuordnen jeder Entität, sondern verwendet nur die generierte Methode "vanilla" für den Delegaten. Hier ist der Code des erzeugten Methode:

@Override 
public Set<DimensionItemTreeDTO> missionSetToTreeDtoSet(Set<Mission> set) { 
    return delegate.missionSetToTreeDtoSet(set); 
} 

Die delegierte Methode selbst ist nicht bekannt, der Dekorateur und ruft die einzelnen Artikel Abbildungsverfahren auf sich selbst:

@Override 
public Set<DimensionItemTreeDTO> missionSetToTreeDtoSet(Set<Mission> set) { 
    if (set == null) { 
     return null; 
    } 

    Set<DimensionItemTreeDTO> set__ = new HashSet<DimensionItemTreeDTO>(); 
    for (Mission mission : set) { 
     set__.add(missionToTreeDto(mission)); //here the decorator is not called ! 
    } 

    return set__; 
} 

... und das dekorierte Verfahren wird nie für die Elemente in der Sammlung aufgerufen.

Gibt es eine Möglichkeit, dass ich Mapstruct die Decorator-Methode in den Auflistungszuordnungen verwenden kann, ohne die Auflistungsmethode manuell in meinem Decorator zu schreiben (was funktioniert, aber ausführlich ist und den Zweck von MapStruct zunichte macht um diese Art von Code nicht schreiben zu müssen)?

Antwort

4

ich die Lösung für mein Problem gefunden: eigentlich war mein Anwendungsfall besser geeignet für die MapStruct @AfterMapping methods, habe ich es und es funktioniert jetzt für alle Fälle gut:

@Mapper 
public abstract class ConstraintsPostProcessor { 

    @Inject 
    private UserService userService; // can use normal Spring DI here 

    @AfterMapping 
    public void setConstraintsOnMissionTreeDTO(Mission mission, @MappingTarget MissionDTO dto){ // do not forget the @MappingTarget annotation or it will not work 
     dto.setUser(userService.getCurrentUser()); // can do any additional logic here, using services etc. 
    } 
} 

Und im Haupt Mapper:

@Mapper(uses = {ConstraintsPostProcessor.class}) // just add the previous class here in the uses attribute 
public interface DimensionMapper { 
    ... 
} 
Verwandte Themen