[[controlling-nested-bean-mappings]]
=== Controlling nested bean mappings

As explained above, MapStruct will generate a method based on the name of the source and target property. Unfortunately, in many occasions these names do not match.

The ‘.’ notation in an `@Mapping` source or target type can be used to control how properties should be mapped when names do not match.
There is an elaborate https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-nested-bean-mappings[example] in our examples repository to explain how this problem can be overcome.

In the simplest scenario there’s a property on a nested level that needs to be corrected.
Take for instance a property `fish` which has an identical name in `FishTankDto` and `FishTank`.
For this property MapStruct automatically generates a mapping: `FishDto fishToFishDto(Fish fish)`.
MapStruct cannot possibly be aware of the deviating properties `kind` and `type`.
Therefore this can be addressed in a mapping rule: `@Mapping(target="fish.kind", source="fish.type")`.
This tells MapStruct to deviate from looking for a name `kind` at this level and map it to `type`.

.Mapper controlling nested beans mappings I
====
[source, java, linenums]
[subs="verbatim,attributes"]
----
@Mapper
public interface FishTankMapper {

    @Mapping(target = "fish.kind", source = "fish.type")
    @Mapping(target = "fish.name", ignore = true)
    @Mapping(target = "ornament", source = "interior.ornament")
    @Mapping(target = "material.materialType", source = "material")
    @Mapping(target = "quality.report.organisation.name", source = "quality.report.organisationName")
    FishTankDto map( FishTank source );
}
----
====

The same constructs can be used to ignore certain properties at a nesting level, as is demonstrated in the second `@Mapping` rule.

MapStruct can even be used to “cherry pick” properties when source and target do not share the same nesting level (the same number of properties).
This can be done in the source – and in the target type. This is demonstrated in the next 2 rules: `@Mapping(target="ornament", source="interior.ornament")` and `@Mapping(target="material.materialType", source="material")`.

The latter can even be done when mappings first share a common base.
For example: all properties that share the same name of `Quality` are mapped to `QualityDto`.
Likewise, all properties of `Report` are mapped to `ReportDto`, with one exception: `organisation` in `OrganisationDto` is left empty (since there is no organization at the source level).
Only the `name` is populated with the `organisationName` from `Report`.
This is demonstrated in `@Mapping(target="quality.report.organisation.name", source="quality.report.organisationName")`

Coming back to the original example: what if `kind` and `type` would be beans themselves?
In that case MapStruct would again generate a method continuing to map.
Such is demonstrated in the next example:


.Mapper controlling nested beans mappings II
====
[source, java, linenums]
[subs="verbatim,attributes"]
----
@Mapper
public interface FishTankMapperWithDocument {

    @Mapping(target = "fish.kind", source = "fish.type")
    @Mapping(target = "fish.name", expression = "java(\"Jaws\")")
    @Mapping(target = "plant", ignore = true )
    @Mapping(target = "ornament", ignore = true )
    @Mapping(target = "material", ignore = true)
    @Mapping(target = "quality.document", source = "quality.report")
    @Mapping(target = "quality.document.organisation.name", constant = "NoIdeaInc" )
    FishTankWithNestedDocumentDto map( FishTank source );

}
----
====

Note what happens in `@Mapping(target="quality.document", source="quality.report")`.
`DocumentDto` does not exist as such on the target side. It is mapped from `Report`.
MapStruct continues to generate mapping code here. That mapping itself can be guided towards another name.
This even works for constants and expression. Which is shown in the final example: `@Mapping(target="quality.document.organisation.name", constant="NoIdeaInc")`.

MapStruct will perform a null check on each nested property in the source.

[TIP]
====
Instead of configuring everything via the parent method we encourage users to explicitly write their own nested methods.
This puts the configuration of the nested mapping into one place (method) where it can be reused from several methods in the upper level,
instead of re-configuring the same things on all of those upper methods.
====

[NOTE]
====
In some cases the `ReportingPolicy` that is going to be used for the generated nested method would be `IGNORE`.
This means that it is possible for MapStruct not to report unmapped target properties in nested mappings.
====
