|
| 1 | +--- |
| 2 | +title: "Native Optional support, improved Kotlin Support, and much more: MapStruct 1.7.0.Beta1 is out" |
| 3 | +author: Filip Hrisafov |
| 4 | +date: "2026-02-01" |
| 5 | +tags: [release, news] |
| 6 | +--- |
| 7 | + |
| 8 | +It's my pleasure to announce the first Beta release of MapStruct 1.7. |
| 9 | + |
| 10 | +The new release comes with a lot of new functionality, e.g.: |
| 11 | + |
| 12 | +* Native `Optional` support |
| 13 | +* Improved Kotlin support |
| 14 | +* Support for Java 21 Sequenced Collections |
| 15 | +* Support for ignoring multiple target properties at once |
| 16 | + |
| 17 | +<!--more--> |
| 18 | + |
| 19 | +Altogether, not less than [41 issues](https://github.com/mapstruct/mapstruct/issues?q=milestone%3A1.7.0.Beta1) were fixed for this release. |
| 20 | + |
| 21 | +This would not have been possible without our fantastic community of contributors: |
| 22 | + |
| 23 | +* [@xumk](https://github.com/xumk) |
| 24 | +* [@cuzfrog](https://github.com/cuzfrog) |
| 25 | +* [@MelleD](https://github.com/MelleD) |
| 26 | +* [@codeswithritesh](https://github.com/codeswithritesh) |
| 27 | +* [@Obolrom](https://github.com/Obolrom) |
| 28 | +* [@tangyang9464](https://github.com/tangyang9464) |
| 29 | +* [@Zegveld](https://github.com/Zegveld) |
| 30 | +* [@rmschots](https://github.com/rmschots) |
| 31 | +* [@zyberzebra](https://github.com/zyberzebra) |
| 32 | +* [@SamilCan](https://github.com/SamilCan) |
| 33 | + |
| 34 | +Thank you everyone for all your hard work! |
| 35 | + |
| 36 | +We are also accepting donations through https://opencollective.com/mapstruct[Open Collective] or https://github.com/sponsors/mapstruct[GitHub]. |
| 37 | +We'd like to thank all the supporters that supported us with donations in this period: |
| 38 | + |
| 39 | +* [adesso SE](https://github.com/adessoSE) |
| 40 | +* [Cybozu](https://github.com/cybozu) |
| 41 | +* [Frederik Hahne](https://opencollective.com/atomfrede) |
| 42 | +* [Lansana](https://opencollective.com/lansana) |
| 43 | +* [Mercedes-Benz Group](https://github.com/mercedes-benz) |
| 44 | +* [Miikka Ylätalo](https://github.com/TotallyMehis) |
| 45 | +* [@pmkyl](https://github.com/pmkyl) |
| 46 | +* [VEMA eG](https://github.com/vemaeg) |
| 47 | +* [znight1020](https://github.com/znight1020) |
| 48 | + |
| 49 | + |
| 50 | +Enough of the pep talk, let's take a closer look at some of the new features and enhancement! |
| 51 | + |
| 52 | +### Native Optional support |
| 53 | + |
| 54 | +It is now possible to use `java.util.Optional` as a return and source type in MapStruct. |
| 55 | +We are also supporting mapping optional properties. |
| 56 | + |
| 57 | +e.g. |
| 58 | + |
| 59 | +{{< prettify java >}} |
| 60 | +@Mapper |
| 61 | +public interface CustomerMapper { |
| 62 | + |
| 63 | + Optional<CustomerDto> map(Customer customer); |
| 64 | +} |
| 65 | +{{< /prettify >}} |
| 66 | + |
| 67 | +Will generate something like |
| 68 | + |
| 69 | +{{< prettify java >}} |
| 70 | +// GENERATED CODE |
| 71 | +public class CustomerMapperImpl implements CustomerMapper { |
| 72 | + |
| 73 | + @Override |
| 74 | + public Optional<CustomerDto> map(Customer customer) { |
| 75 | + if ( customer == null ) { |
| 76 | + return Optional.empty(); |
| 77 | + } |
| 78 | + |
| 79 | + CustomerDto customerDto = new CustomerDto(); |
| 80 | + // ... |
| 81 | + if ( customer.getName().isPresent() ) { |
| 82 | + customerDto.setName( customer.getName().get() ); |
| 83 | + } |
| 84 | + // ... |
| 85 | + |
| 86 | + return Optional.of( customerDto ); |
| 87 | + } |
| 88 | + |
| 89 | + // ... |
| 90 | +} |
| 91 | +{{< /prettify >}} |
| 92 | + |
| 93 | +Note that we are not doing any `null` checks for the optional properties. |
| 94 | +Instead, we do a check if the optional is present or not and map it. |
| 95 | +There is also support for mapping `OptionalDouble` and `OptionalInt`. |
| 96 | +The standard MapStruct out-of-the-box conversions are supported by unwrap the optional. |
| 97 | + |
| 98 | +### Improved Kotlin support |
| 99 | + |
| 100 | +Support for Kotlin has been generally improved across the board. |
| 101 | + |
| 102 | +MapStruct now natively detects that a class is a Kotlin data class and treats it accordingly when generating mappings. |
| 103 | +This means that single field data classes, data classes with multiple constructors and constructors with all default parameters work as expected. |
| 104 | + |
| 105 | +Additionally, we have added support for Kotlin's sealed classes as part of our `@SubclassMapping` support. |
| 106 | + |
| 107 | +To use MapStruct with Kotlin, you need to add the following dependency to your project: |
| 108 | + |
| 109 | +#### Maven |
| 110 | + |
| 111 | +{{< prettify xml >}} |
| 112 | +<plugin> |
| 113 | + <groupId>org.apache.maven.plugins</groupId> |
| 114 | + <artifactId>maven-compiler-plugin</artifactId> |
| 115 | + <version>3.14.1</version> <!-- or newer version --> |
| 116 | + <configuration> |
| 117 | + <source>${java.version}</source> <!-- depending on your project --> |
| 118 | + <target>${java.version}</target> <!-- depending on your project --> |
| 119 | + <annotationProcessorPaths> |
| 120 | + <path> |
| 121 | + <groupId>org.mapstruct</groupId> |
| 122 | + <artifactId>mapstruct-processor</artifactId> |
| 123 | + <version>${mapstruct.version}</version> |
| 124 | + </path> |
| 125 | + <path> |
| 126 | + <groupId>org.jetbrains.kotlin</groupId> |
| 127 | + <artifactId>kotlin-metadata-jvm</artifactId> |
| 128 | + <version>${kotlin.version}</version> |
| 129 | + </path> |
| 130 | + <!-- other annotation processors --> |
| 131 | + </annotationProcessorPaths> |
| 132 | + </configuration> |
| 133 | +</plugin> |
| 134 | +{{< /prettify >}} |
| 135 | + |
| 136 | +#### Gradle |
| 137 | + |
| 138 | +{{< prettify groovy >}} |
| 139 | +dependencies { |
| 140 | + ... |
| 141 | + |
| 142 | + annotationProcessor 'org.mapstruct:mapstruct-processor:${mapstruct.version}' |
| 143 | + annotationProcessor 'org.jetbrains.kotlin:kotlin-metadata-jvm:${kotlin.version}' |
| 144 | +} |
| 145 | +{{< /prettify >}} |
| 146 | + |
| 147 | +We also have something in the pipeline for KSP, so stay tuned! |
| 148 | + |
| 149 | +### Support for Java 21 Sequenced Collections |
| 150 | + |
| 151 | +When using Java 21 Sequenced Collections, MapStuct will generate the appropriate underlying implementation. |
| 152 | + |
| 153 | +* `SequencedSet` - This will generate a `SequencedSet` implementation using the underlying `LinkedHashSet` implementation. |
| 154 | +* `SequencedMap` - This will generate a `SequencedMap` implementation using the underlying `LinkedHashMap` implementation. |
| 155 | + |
| 156 | +### Support for ignoring multiple target properties at once |
| 157 | + |
| 158 | +A new annotation `@Ignored` has been added to support ignoring multiple target properties at once. |
| 159 | +Instead of writing: |
| 160 | + |
| 161 | +{{< prettify java >}} |
| 162 | +@Mapper |
| 163 | +public interface AnimalMapper { |
| 164 | + |
| 165 | + @Mapping( target = "publicAge", ignore = true ) |
| 166 | + @Mapping( target = "age", ignore = true ) |
| 167 | + @Mapping( target = "publicColor", ignore = true ) |
| 168 | + @Mapping( target = "color", ignore = true ) |
| 169 | + AnimalDto animalToDto( Animal animal ); |
| 170 | + |
| 171 | +} |
| 172 | +{{< /prettify >}} |
| 173 | + |
| 174 | +You can now write: |
| 175 | + |
| 176 | +{{< prettify java >}} |
| 177 | +@Mapper |
| 178 | +public interface AnimalMapper { |
| 179 | + |
| 180 | + @Ignored( targets = { "publicAge", "age", "publicColor", "color" } ) |
| 181 | + AnimalDto animalToDto( Animal animal ); |
| 182 | + |
| 183 | +} |
| 184 | +{{< /prettify >}} |
| 185 | + |
| 186 | +### Enhancements |
| 187 | + |
| 188 | +* Add support for locale parameter for `numberFormat` and `dateFormat` in `@Mapping` annotation. |
| 189 | +* Detect Builder without a factory method. i.e., if there is an inner class that ends with `Builder` and has a constructor with parameters, |
| 190 | + it will be treated as a potential builder. |
| 191 | + Builders through static methods on the type have a precedence. |
| 192 | +* Add support for custom exception for subclass exhaustive strategy for `@SubclassMapping` mapping. Available on `@BeanMapping`, `@Mapper` and `@MappingConfig`. |
| 193 | +* Add new `NullValuePropertyMappingStrategy#CLEAR` for clearing Collection and Map properties when updating a bean |
| 194 | +* Support `@AnnotatedWith` on decorators |
| 195 | + |
| 196 | +### Enhancements with behavior changes |
| 197 | + |
| 198 | +* Add warning/error for redundant `ignoreUnmappedSourceProperties` entries - If a source property that is mapped is also ignored there will be a warning/error. |
| 199 | + The `unmappedSourcePolicy` can be used to control this behavior. |
| 200 | +* Warning when the target has no target properties. |
| 201 | +* Initialize `Optional` with `Optional.empty` instead of `null` - Before this change, MapStruct would use `null` to initialize an `Optional` target property. |
| 202 | +* Mark `String` to `Number` as lossy conversion - This is similar to the behavior of `long` to `int` conversion. |
| 203 | + The `ReportingPolicy` on the `typeConversionPolicy` will be used to determine how to report the lossy conversion. |
| 204 | + |
| 205 | +### Download |
| 206 | + |
| 207 | +This concludes our tour through MapStruct 1.7 Beta1. |
| 208 | +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: |
| 209 | + |
| 210 | +* Annotation JAR: [org.mapstruct:mapstruct:1.7.0.Beta1](http://search.maven.org/#artifactdetails|org.mapstruct|mapstruct|1.7.0.Beta1|jar) |
| 211 | +* Annotation processor JAR: [org.mapstruct:mapstruct-processor:1.7.0.Beta1](http://search.maven.org/#artifactdetails|org.mapstruct|mapstruct-processor|1.7.0.Beta1|jar) |
| 212 | + |
| 213 | +Alternatively, you can get ZIP and TAR.GZ distribution bundles - containing all the JARs, documentation etc. - [from GitHub](https://github.com/mapstruct/mapstruct/releases/tag/1.7.0.Beta1). |
| 214 | + |
| 215 | +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: |
| 216 | + |
| 217 | +* Get help in our https://github.com/mapstruct/mapstruct/discussions[GitHub Discussions] or https://stackoverflow.com/questions/tagged/mapstruct[StackOverflow] |
| 218 | +* Report bugs and feature requests via the [issue tracker](https://github.com/mapstruct/mapstruct/issues) |
| 219 | +* Follow [@GetMapStruct](https://twitter.com/GetMapStruct) on Twitter |
0 commit comments