MapStructとは
Entity(またはDomain)からDTOへの変換を助けてくれるライブラリです。
有名なMappingライブリとしては、Structs1.xのBeanUtilsや、ModelMapper・Dozerなどがあります。
MapStructの特徴は、Lombokと同じようにアノテーションプロセッサーを用いてコードを自動生成しているため、
ガリガリと自力でgetter/setterを用いてマッピングするのと同じぐらいに高速な点が特徴です。
性能については、下記記事で紹介されています。
Performance of Java 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のサンプルコードで稼働し、
MapStructのReadmeでは動作しませんでした(ドハマりしました)。
以下のようにpomを記載し、
eclipseでプロジェクトを選択し、実行 ⇒ maven install または maven testでコートが生成され、
mapstruct-lombokで記載されているテストコードが成功します。
残念ながら、eclipseの自動ビルドやクリーンによるビルドではコードが生成されません
IDE Supportは用意されており、「annotation processors」を自動で実行するように作られているのですが、
肝心の「annotation processors」をMavenに設定すると動かなくなるためです
<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パターン代表例
<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の項目で、「java.annotations.common」を有効化するように記載がされています。
その、java.annotations.commonがJava9で、java.xml.ws .annotation にリネームされていましたが、
なんと、Java11で、java.xml.ws.annotationが削除されています
今のところ、OKパターンのpom.xmlを記載し、mavenビルドを実行すれば、コードが生成され、
期待通り動くことは確認していますが、リスクがある可能性はご了承下さい
まとめ
本記事では、MapStructをlombokとJava11で使用する方法について記載しました。
実際のMapStructの使い方については、他のQiita記事や、本家のサンプルコードをご参考下さい。
ちょっと嵌るポイントもありますが、
自力でgetter/setterを記載して、バグを出す可能性を引くより、何百倍もコードを書くのが楽しくなります。
あなたのJavaライフにちょっと貢献出来たら幸いです。