I recently ran into a subtle but critical issue while working with MapStruct in a Spring Boot application — one that broke production after deployment and took hours to debug.
This wasn’t a complex algorithmic bug or a database issue. It was a single annotation: @Named.
Let me walk you through what happened, why it happened, and what you should learn from it.
The Setup
In our codebase, we use MapStruct extensively to convert Entities into DTOs and vice versa. A typical mapper looks like this:
@Mapper(componentModel = "spring")
public interface AddressMapper {
@Mapping(target = "longitude", source = "coordinates", qualifiedByName = "extractLongitude")
@Mapping(target = "latitude", source = "coordinates", qualifiedByName = "extractLatitude")
AddressResponse toDto(Address address);
}
This toDto() method was used in multiple places across the system. Everything worked perfectly.
The Mistake
Later, while working on another feature, I added an explicit reference to this method. Without fully understanding the implications, I added:
@Named("toDto")
AddressResponse toDto(Address address);
It felt harmless. Even “correct”.
But it wasn’t.
What Happened After Deployment
After deploying the change, parts of the system started breaking.
- Some APIs returned incomplete data
- No compilation errors
- No obvious runtime exceptions
Just silently incorrect responses.
The Root Cause
The issue lies in how MapStruct treats methods annotated with @Named.
Before adding @Named:
MapStruct automatically used toDto(Address) wherever it needed to map:
Address → AddressResponse
After adding @Named:
That same method became a qualified mapping method.
And here’s the critical part:
MapStruct no longer considers qualified methods for automatic mapping.
So, unless you explicitly specify:
@Mapping(target = "address", source = "address", qualifiedByName = "toDto")
MapStruct will ignore that method entirely.
Why This Broke the System
Because:
- The method was widely used implicitly
- Adding
@Namedchanged its behavior globally - Existing mappings were not updated to use
qualifiedByName
So MapStruct stopped mapping Address → AddressResponse in many places.
Why It Was Hard to Debug
This bug was tricky because:
- There were no compile-time errors
- No clear runtime exceptions
- The system partially worked
- Only specific mappings failed
The failure was silent.
The Fix
The fix was simple:
👉 Remove @Named from the method
OR
👉 Explicitly use it everywhere with qualifiedByName
In my case, removing it was the correct choice because it was a default mapping method.
Key Lessons
1. @Named Changes Method Visibility
Adding @Named is not just labeling—it changes how MapStruct selects methods.
2. Default Mappers Should NOT Use @Named
If a method is your primary mapping for a type pair:
Address → AddressResponse
Do NOT annotate it with @Named.
3. Use @Named Only for Special Cases
Use it when you have multiple mapping strategies:
@Named("summary")
AddressSummaryDto toSummary(Address address);
@Named("detailed")
AddressDetailDto toDetailed(Address address);
4. Always Check Generated Code
MapStruct generates code under:
target/generated-sources/annotations
If something feels off, check what it actually generated.
5. Small Annotation, Big Impact
This was a one-line change that caused a production issue.
It reinforced an important lesson:
In frameworks like MapStruct, small annotations can have system-wide effects.
Final Thoughts
MapStruct is incredibly powerful and efficient, but it’s also very strict in how it resolves mappings.
Understanding these internal behaviors is crucial when working in large codebases.
If you’re using MapStruct:
- Be intentional with
@Named - Avoid modifying shared mapping methods casually
- And always think about how changes affect existing mappings
If this saves even one debugging session for someone, it was worth writing.
Happy coding!





