mapstruct / mapstruct/mapstruct

Map with immutable target

Offen
#2,155 7 Kommentare 8 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

feature up-for-grabs
Vorherrschende Sprache
Java
Sterne
7.7k
Forks
1.1k
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

(not really a bug, but more of an improvement)

Mapstruct apparently offers no way to map with an immutable "target".

**Context:**
We have a CarDto and a Car that are both immutable and use a builder generated via Lombok

```java
@Value
@Builder(toBuilder=true)
class Car {
final String color;
final double price;
final int hiddenField;
}

@Value
@Builder(toBuilder=true)
class CarDto {
final String color;
final double price;
}
```
A standard mapping like
```java
@Mapper
class CarMapper {
Car toEntity(CarDto dto);
}
```
works as intended. The generated mapper creates a new CarBuilder, fill the fields and then return the built entity

**The issue:**
As we have `hiddenField` which is not present in the DTO, when we have an API call to update the `Car` entity we need to map the given DTO to the existing entity to preserve the value of the field.

So naively I'd do:
```java
@Mapper
class CarMapper {
Car toEntity(CarDto dto, @MappingTarget Car existingCar);
}
```

However mapstruct doesn't seem to support this use case with an immutable target. And as the documentation clearly states:
> you may also set the method’s return type to the type of the target parameter, which will cause the generated implementation to update the passed mapping target and return it as well.

So yeah, it does not create a copy of the `Car`, it tries to update the given one... And as there are no setter, it doesn't do anything.

As mapstruct supports the builder pattern for regular mapping, it'd be great if mapstruct could get the existing entity, call `toBuilder` on it and then do the mapping as usual.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne mit der vorhandenen Builder-Unterstützung von MapStruct und der Behandlung von @MappingTarget und verwende dabei die Car- und CarDto-Beispiele in diesem Issue als erwartetes Szenario. Ermittle, wie ein unveränderliches Zielobjekt über toBuilder() kopiert, gemappt und zurückgegeben werden kann, wobei Felder erhalten bleiben, die in der Quelle fehlen; als abgeschlossen gilt die Unterstützung dieses Verhaltens ohne Setter.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
java
Bereich
tooling
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.