Based on the official MapStruct documentation and best practices, here are recommendations for mapping entities and their relationships, especially when dealing with collections and nested mappings:

  1. Mapping Collections: MapStruct can automatically handle the mapping of collections, such as List or Set, provided that appropriate mapping methods for the element types are defined. For instance, to map a Set<Person> to a Set<PersonDTO>, ensure that a mapping method from Person to PersonDTO exists. MapStruct will utilize this method to map each element in the collection.
  2. Mapping Nested Entities: When dealing with nested entities, define mapping methods for each nested type. MapStruct will recursively use these methods to map nested objects. For example, if a Team entity contains a collection of Person entities, and you have a method to map Person to PersonDTO, MapStruct can map the nested Person entities within Team automatically.
  3. Handling Bi-Directional Relationships: Bi-directional relationships can lead to infinite loops during mapping. To prevent this, consider using the @InheritConfiguration annotation to reuse configurations and control the mapping process carefully. Additionally, using the @Context annotation can help manage cycles by maintaining state during the mapping process.
  4. Using @Context for Dependency Injection: For mappings that require external services or components (e.g., resolving entities by IDs), you can use the @Context annotation to pass such dependencies into your mapping methods. This approach allows you to inject services like EntityResolverService into your mappers, enabling database lookups or other operations during the mapping process.
  5. Component Model Configuration: To integrate MapStruct with frameworks like Spring, set the componentModel attribute to "spring" in the @Mapper annotation. This configuration ensures that the generated mapper is a Spring bean and can be injected where needed.
  6. Mapping Strategies for Complex Scenarios: In scenarios where automatic mapping is insufficient (e.g., differing field names or complex transformations), use the @Mapping annotation to specify source and target mappings explicitly. This approach provides fine-grained control over the mapping process.

By implementing these strategies, you can effectively manage complex mappings in your application, leveraging MapStruct's capabilities to handle collections, nested entities, and integration with external services.

Source: https://techlab.bol.com/en/blog/mapping-object-models-case-study/