Как обеспечить совместную работу MapStruct и Lombok в проекте?

«Как обеспечить совместную работу MapStruct и Lombok в проекте?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

MapStruct и Lombok — это аннотационные процессоры, которые должны выполняться в правильном порядке во время компиляции. Lombok должен сгенерировать геттеры, сеттеры и билдеры до того, как MapStruct начнет анализировать классы для создания мапперов.

Проблема: Без настройки порядок обработки может быть случайным, и MapStruct не «увидит» сгенерированных Lombok методов, что приведет к ошибкам компиляции.

Решение: Явное указание порядка процессоров в сборке.

Для Maven (pom.xml):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <annotationProcessorPaths>
            <!-- Сначала Lombok -->
            <path>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </path>
            <!-- Затем MapStruct -->
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>${mapstruct.version}</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

Для Gradle (build.gradle):

dependencies {
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok' // Первый

    implementation "org.mapstruct:mapstruct:${mapstructVersion}"
    annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" // Второй
}

Дополнительная настройка для Builder: Если MapStruct использует паттерн Builder (через builder = @Builder(disableBuilder = false)), убедитесь, что в Lombok-сущности есть @Builder вместе с @NoArgsConstructor и @AllArgsConstructor.