Native Optional support, improved Kotlin Support, and much more: MapStruct 1.7.0.Beta1 is out
It’s my pleasure to announce the first Beta release of MapStruct 1.7.
The new release comes with a lot of new functionality, e.g.:
- Native
Optionalsupport - Improved Kotlin support
- Support for Java 21 Sequenced Collections
- Support for ignoring multiple target properties at once
Altogether, not less than 41 issues were fixed for this release.
This would not have been possible without our fantastic community of contributors:
- @xumk
- @cuzfrog
- @MelleD
- @codeswithritesh
- @Obolrom
- @tangyang9464
- @Zegveld
- @rmschots
- @zyberzebra
- @SamilCan
Thank you everyone for all your hard work!
We are also accepting donations through https://opencollective.com/mapstruct[Open Collective] or https://github.com/sponsors/mapstruct[GitHub]. We’d like to thank all the supporters that supported us with donations in this period:
- adesso SE
- Cybozu
- Frederik Hahne
- Lansana
- Mercedes-Benz Group
- Miikka Ylätalo
- @pmkyl
- VEMA eG
- znight1020
Enough of the pep talk, let’s take a closer look at some of the new features and enhancement!
Native Optional support
It is now possible to use java.util.Optional as a return and source type in MapStruct.
We are also supporting mapping optional properties.
e.g.
@Mapper
public interface CustomerMapper {
Optional<CustomerDto> map(Customer customer);
}
Will generate something like
// GENERATED CODE
public class CustomerMapperImpl implements CustomerMapper {
@Override
public Optional<CustomerDto> map(Customer customer) {
if ( customer == null ) {
return Optional.empty();
}
CustomerDto customerDto = new CustomerDto();
// ...
if ( customer.getName().isPresent() ) {
customerDto.setName( customer.getName().get() );
}
// ...
return Optional.of( customerDto );
}
// ...
}
Note that we are not doing any null checks for the optional properties.
Instead, we do a check if the optional is present or not and map it.
There is also support for mapping OptionalDouble and OptionalInt.
The standard MapStruct out-of-the-box conversions are supported by unwrap the optional.
Improved Kotlin support
Support for Kotlin has been generally improved across the board.
MapStruct now natively detects that a class is a Kotlin data class and treats it accordingly when generating mappings. This means that single field data classes, data classes with multiple constructors and constructors with all default parameters work as expected.
Additionally, we have added support for Kotlin’s sealed classes as part of our @SubclassMapping support.
To use MapStruct with Kotlin, you need to add the following dependency to your project:
Maven
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version> <!-- or newer version -->
<configuration>
<source>${java.version}</source> <!-- depending on your project -->
<target>${java.version}</target> <!-- depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-metadata-jvm</artifactId>
<version>${kotlin.version}</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
Gradle
dependencies {
...
annotationProcessor 'org.mapstruct:mapstruct-processor:${mapstruct.version}'
annotationProcessor 'org.jetbrains.kotlin:kotlin-metadata-jvm:${kotlin.version}'
}
We also have something in the pipeline for KSP, so stay tuned!
Support for Java 21 Sequenced Collections
When using Java 21 Sequenced Collections, MapStuct will generate the appropriate underlying implementation.
SequencedSet- This will generate aSequencedSetimplementation using the underlyingLinkedHashSetimplementation.SequencedMap- This will generate aSequencedMapimplementation using the underlyingLinkedHashMapimplementation.
Support for ignoring multiple target properties at once
A new annotation @Ignored has been added to support ignoring multiple target properties at once.
Instead of writing:
@Mapper
public interface AnimalMapper {
@Mapping( target = "publicAge", ignore = true )
@Mapping( target = "age", ignore = true )
@Mapping( target = "publicColor", ignore = true )
@Mapping( target = "color", ignore = true )
AnimalDto animalToDto( Animal animal );
}
You can now write:
@Mapper
public interface AnimalMapper {
@Ignored( targets = { "publicAge", "age", "publicColor", "color" } )
AnimalDto animalToDto( Animal animal );
}
Enhancements
- Add support for locale parameter for
numberFormatanddateFormatin@Mappingannotation. - Detect Builder without a factory method. i.e., if there is an inner class that ends with
Builderand has a constructor with parameters, it will be treated as a potential builder. Builders through static methods on the type have a precedence. - Add support for custom exception for subclass exhaustive strategy for
@SubclassMappingmapping. Available on@BeanMapping,@Mapperand@MappingConfig. - Add new
NullValuePropertyMappingStrategy#CLEARfor clearing Collection and Map properties when updating a bean - Support
@AnnotatedWithon decorators
Enhancements with behavior changes
- Add warning/error for redundant
ignoreUnmappedSourcePropertiesentries - If a source property that is mapped is also ignored there will be a warning/error. TheunmappedSourcePolicycan be used to control this behavior. - Warning when the target has no target properties.
- Initialize
OptionalwithOptional.emptyinstead ofnull- Before this change, MapStruct would usenullto initialize anOptionaltarget property. - Mark
StringtoNumberas lossy conversion - This is similar to the behavior oflongtointconversion. TheReportingPolicyon thetypeConversionPolicywill be used to determine how to report the lossy conversion.
Download
This concludes our tour through MapStruct 1.7 Beta1. If you’d like to try out the features described above, you can fetch the new release from Maven Central using the following GAV coordinates:
- Annotation JAR: org.mapstruct:mapstruct:1.7.0.Beta1
- Annotation processor JAR: org.mapstruct:mapstruct-processor:1.7.0.Beta1
Alternatively, you can get ZIP and TAR.GZ distribution bundles - containing all the JARs, documentation etc. - from GitHub.
If you run into any trouble or would like to report a bug, feature request or similar, use the following channels to get in touch:
- Get help in our https://github.com/mapstruct/mapstruct/discussions[GitHub Discussions] or https://stackoverflow.com/questions/tagged/mapstruct[StackOverflow]
- Report bugs and feature requests via the issue tracker
- Follow @GetMapStruct on Twitter