A follow-up to Java Records deserve a mapper

My earlier post introduced Immuto and made the general case for a mapper designed around Records from day one. This one is narrower and more specific: it walks through exactly where MapStruct, which is the mapper most Java teams already use, runs into friction with Records, with real annotations and real generated code on both sides.

MapStruct is excellent. It’s been the go-to compile-time mapper for a decade, and it has supported Records since 1.4.0 by generating direct calls to the canonical constructor. That part works well. To be fair to it upfront: if your Record fields line up cleanly with your entity fields, MapStruct handles that today with no builder and no factory. The gaps below are specific and narrower than “MapStruct can’t do Records,” since they show up in particular corners: asymmetric mappings, defaults, null handling, and sealed hierarchies.

1.Asymmetric mappings and the reverse direction

Where MapStruct’s constructor-based mapping gets genuinely difficult is asymmetric mappings, meaning cases where a target constructor parameter is built from more than one source field via an expression, and you also want the reverse mapping generated automatically.