高速Mappingライブリ MapStructをLombokとJava11で使用する

# MapStructとは

Entity(またはDomain)からDTOへの変換を助けてくれるライブラリです。
有名なMappingライブリとしては、Structs1.xのBeanUtilsや、ModelMapper・Dozerなどがあります。

MapStructの特徴は、Lombokと同じようにアノテーションプロセッサーを用いてコードを自動生成しているため、
ガリガリと自力でgetter/setterを用いてマッピングするのと同じぐらいに高速な点が特徴です。

性能については、下記記事で紹介されています。
[Performance of Java Mapping Frameworks](https://www.baeldung.com/java-performance-mapping-frameworks)

主観となりますが、性能だけでなく、他のマッピングツールと比較しても、コードが直観的で解りやすいと感じています。

そんな素敵なMappingツールですが、ちょっと導入に色々と嵌ってしまった & 同様の記事が見つからなかったため、本記事を記載しています。

## 環境
Lombok Changelogによると1.8.2で、MapStructとのIntegrationについてのバグが修正されているようです

・Pleiades Eclipse 2018-09(※Lombok1.8.2)
・AdoptOpenJDK 11
・Lombok1.8.2
・MapStruct 1.2.0.Final および 1.3.0.Beta1

## OKパータンの設定
結論としては、[mapstruct-lombok](https://github.com/mapstruct/mapstruct-examples)のサンプルコードで稼働し、
[MapStructのReadme](https://github.com/mapstruct/mapstruct)では動作しませんでした(ドハマりしました)。

以下のようにpomを記載し、
**eclipseでプロジェクトを選択し、実行 ⇒ maven install または maven test**でコートが生成され、
[mapstruct-lombok](https://github.com/mapstruct/mapstruct-examples)で記載されているテストコードが成功します。

残念ながら、eclipseの自動ビルドやクリーンによるビルドではコードが生成されません:sob:
[IDE Support](http://mapstruct.org/documentation/ide-support/)は用意されており、「annotation processors」を自動で実行するように作られているのですが、
**肝心の「annotation processors」をMavenに設定すると動かなくなるためです:innocent:**

```pom.xml 

    <properties>
        <org.mapstruct.version>1.3.0.Beta1</org.mapstruct.version> ※ 1.2.0.Finalも動作することを確認済み
        <org.projectlombok.version>1.18.2</org.projectlombok.version>
    </properties>
<!-- 省略 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>　※Readmeとの差異になります
            <version>${org.mapstruct.version}</version>
            <scope>provided</scope>　※ コンパイル時に実行するように記載されています
        </dependency>
<!-- 省略 -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>　※ ポイント Readmeで記載されているAnnotation-processorが記載されていない
                    <version>3.6.2</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
```

## NGパターン代表例

```pom.xml
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.5.1</version>
            <configuration>
                <source>1.6</source> <!-- or higher, depending on your project -->
                <target>1.6</target> <!-- or higher, depending on your project -->
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.mapstruct</groupId>
                        <artifactId>mapstruct-processor</artifactId>　※ ← 少なくとも、Java11では動かないようです
                        <version>${org.mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
```

## Java11の影響について
公式ドキュメントでは、[using_mapstruct_on_java_9](http://mapstruct.org/documentation/stable/reference/html/#_using_mapstruct_on_java_9)の項目で、「java.annotations.common」を有効化するように記載がされています。
その、java.annotations.commonがJava9で、java.xml.ws .annotation にリネームされていましたが、
**なんと、Java11で、java.xml.ws.annotationが削除されています :innocent: :innocent: :innocent:**

今のところ、OKパターンのpom.xmlを記載し、mavenビルドを実行すれば、コードが生成され、
期待通り動くことは確認していますが、リスクがある可能性はご了承下さい

## まとめ
本記事では、MapStructをlombokとJava11で使用する方法について記載しました。
実際のMapStructの使い方については、他のQiita記事や、本家のサンプルコードをご参考下さい。

ちょっと嵌るポイントもありますが、
自力でgetter/setterを記載して、バグを出す可能性を引くより、何百倍もコードを書くのが楽しくなります。

あなたのJavaライフにちょっと貢献出来たら幸いです。