MapStruct v1.3.0.Beta1 Release Notes

Release Date: 2018-07-15 // almost 6 years ago
  • ๐Ÿ”‹ Features

    • ๐Ÿ‘Œ Support for Builders (#782 and #802). Support tested with:
      • Lombok - requires having the Lombok classes in a separate module see rzwitserloot/lombok#1538
      • AutoValue
      • Immutables - see (#1415) for more info for the out of the box support
      • FreeBuilder
      • It also works for custom builder if the object being build provides a parameterless public static method for instantiating the builder. Otherwise, you would need to write a custom BuilderProvider
    • โž• Add a NoOpBuilderProvider (#1418) - BuilderProvider that allows users to disable the using of Builders in MapStruct. You need to enable it explicitly by creating a org.mapstruct.ap.spi.BuilderProvider file in the META-INF/services directory with org.mapstruct.ap.spi.NoOpBuilderProvider as its content.
    • ๐Ÿ‘ Out of the box support for Immutables (#1415)
    • โž• Add Constructor Injection for Annotation Based Component Model (#571)
    • โž• Add support for unmappedSourcePolicy (#610)
    • โž• Add support for ignoring source properties (#1317)
    • ๐Ÿ‘ Allow defaultValue to be an expression (#1363) - A new defaultExpression has been added to @Mapping
    • ๐Ÿ— Object factory needs to be considered for builder types as well (#1431)
    • ๐Ÿ”ง Ignore mappings by default (#1392) - With @BeanMapping(ignoreByDefault = true) one can limit the mapping only to the explicitly defined mappings. This annotation actually applies ignore to all target properties, which means that it can be used in configuration mappings to only map explicit properties in base classes
    • Access to Builder type in @BeforeMapping and @AfterMapping (#1433) - NB : Lifecycle methods for the type being build are not invoked yet (see #1454)

    โœจ Enhancements

    • Exceptions in nested beanmapping are not declared in generated code (#1332)
    • @Mapping arguments should be trimmed (#1353)
    • โž• Add implicit conversion between String and java.util.Currency (#1355)
    • Shared configuration not applied when using InheritInverseConfiguration (#1367) - aligning @Inherit(Inverse)Configuration with strategy AUTO_INHERIT_*
    • ๐ŸŽ Extremily low mapstruct-processor performance on Java 9 (#1378) - Use Types when searching for TypeElement(s) instead of getting a new TypeElement each time
    • Report error on the @Mapping annotation when using invalid @Mapping values (#1383)
    • ๐Ÿ‘Œ Improve error message when unknown source parameter is used in @Mapping (#1387)
    • ๐ŸŽ Possible performance improvement of constant / defaultValue primitive to String mappings (#1401) - See behavior changes
    • ๐Ÿ‘ Allow using update mappings for types with builders (#1423)
    • Lazy load SPIs in annotation processor context (#1473)
    • @ObjectFactory not called when on an @Context object (#1398)
    • ๐Ÿ‘ Allow package-private mapper (#1365)
    • โž• Add support for Builders with multiple build methods (#1479) - See PR #1498 for more details

    ๐Ÿ› Bug fixes

    • ๐Ÿ‘ป Context annotation on primitive types with @AfterMapping throws exception on compile (#1339)
    • Enum mapper generates mapping method with wrong signature. Wrong amount of parameters (#1340)
    • Not generating setter methods for all nested constants (#1320)
    • Ignore doesn't work for readonly properties (#1345)
    • Invalid mapper is created when there is no read accessor for nested target mappings (#1375)
    • Injection strategy Constructor does not generate compilable code (#1395)
    • ๐Ÿ”ง Shared configuration not applied when using @InheritInverseConfiguration (#1367)
    • โš  Mapping String to org.joda.time.LocalDate issues compiler error (#1370) - When using date format MapStruct tries to validate it by invoking the Joda formatter. This means that the Joda dependency needs to be on the classpath. If the MapStruct processor is invoked from the processor path, and Joda is not there we can't invoke Joda classes. If this is the case we will now issue a warning saying what the user needs to do (add Joda to the processor path) and consider the format as valid
    • โšก๏ธ MapStruct throws an exception during collection update mapping when target is immutable and there is no target read accessor (#1359)
    • โž• Adder argument cannot be determined when collection type is not generic (#1338)
    • Pass originating elements to the javax.annotation.processing.Filer API (#1414)
    • org.joda.time.LocalDate tojava.time.LocalDate generated code has compilation error (#1425) - With this fix we have also improved the builtin templates, so something similar should not happen again
    • 0๏ธโƒฃ Improper @BeanMapping(ignoreByDefault=true) treatment with Immutable target (#1452)
    • Direct constant assignment causes problems for byte and short values (#1462)
    • โž• Adder method not working for builders (#1449)
    • String to enum conversion: Compile error in generated mapper (#1460) - Ensures the FQN will be used for SimpleConversion if required, something like this should not happen again
    • Compilation error on CollectionMapping. Wrong capture generated (#1453)
    • ๐Ÿ”ง NullPointerException when using unknown source properties with shared configuration (#1180)
    • ZonedDateTime to XmlGregorianCalendar losses time zone information (#1523)
    • Generic mapping method not selected (#1482)
    • โœ… "Ambiguous mapping methods found" when the same method is found twice (#537) - Fixed in an earlier version, but now we have a test for it.

    ๐Ÿ“š Documentation

    • โž• Add IntelliJ Formatter to CONTRIBUTING.md (#1297)
    • ๐Ÿ”„ Change MapStruct Version in README to latest 1.2.0.Final (#1312)
    • ๐Ÿ“„ Injection Strategy docs (#1314)
    • โž• Add since tags for unmappedSourcePolicy() (#1333)
    • โž• Add change of behaviour for constant and defaultValue in @Mapping (#1459)
    • ๐Ÿ‘‰ Use constants instead of strings in @ValueMapping javadoc (PR #1480)
    • ๐Ÿ“š Update documentation about the latest gradle apt plugin (#1419)
    • Document of sample code is broken (PR #1530)
    • โž• Add sample of @Mapping annotation to @InheritInverseConfiguration (#1531)
    • โž• Add documentation about the Builders support (#1417)
    • โž• Add @since tag to @Mapping#defaultExpression() (#1436)

    Behavior

    0๏ธโƒฃ With #1401 MapStruct now tries to check if it is possible to assign a defaultValue and / or a constant directly without doing a conversion. For example for the following mapper:

    @Mapperpublic interface PersonMapper { @Mapping(target = "price", constant = "10.5") @Mapping(target = "age", defaultValue = "10) Order order(OrderDto source); }
    

    Before the following was generated:

    public class PersonMapperImpl implements PersonMapper { @Overridepublic Order order(OrderDto source) { if (source == null) { return null; } Order order = new Order(); order.setConstant(Double.parseDouble("10.5")); if (source.getAge() == null) { order.setAge(Integer.parse("10")); } else { order.setAge(source.getAge()); } return order; } }
    

    And now the following is generated:

    public class PersonMapperImpl implements PersonMapper { @Overridepublic Order order(OrderDto source) { if (source == null) { return null; } Order order = new Order(); order.setConstant(10.5)); if (source.getAge() == null) { order.setAge(10); } else { order.setAge(source.getAge()); } return order; } }
    

    ๐Ÿ“œ On top of that MapStruct the possible values are more and you can use anything that the compiler would consider as a valid integer (for example 10_000). The parse functions don't accept such strings as valid.