modelmapperの曖昧なマッピングを厳密なマッピングに

エキサイト株式会社の中尾です。

今回はModelMapperのよく使われるオプションについて、説明します。

以下の例は、userIdを別のモデルにマッピングします。 userIdからuserIdなのでもちろんテストは通ります。

@ExtendWith(MockitoExtension.class)
public class ModelMapperConfig{

    @Description("ModelMapperConfig")
    @Test
    void test() {
        final ModelMapper modelMapper = new ModelMapper();
        final TestModel testModel = new TestModel();
        testModel.setUserId("nakao");

        final Model map = modelMapper.map(testModel, Model.class);
        Assertions.assertEquals(
                "nakao",
                map.getUserId()
        );
    }

    @Data
    public static class Model{
        private String userId;
    }

    @Data
    public static class TestModel{
        private String userId;
    }
}

別のモデルにしてみましょう。

    @Data
    public static class Model{
        private long id;

        private String userId;
    }

実行します。

userIdからuseridはマッピングされるのですが、 idにもmappingされます!

ModelMapperのデフォルトマッピング設定は曖昧なマッピングだからです!

ModelMapper - Configuration

useridに関わりそうなプロパティを発見し、勝手にmappingします。怖いですね。。。

変数の型も、同一プロパティに合わせて勝手にmappingします。

@ExtendWith(MockitoExtension.class)
public class ModelMapperConfig{

    @Description("ModelMapperConfig")
    @Test
    void docomoMailReturnTrue() {
        final ModelMapper modelMapper = new ModelMapper();
        final TestModel testModel = new TestModel();
        testModel.setUserId(1);

        final Model map = modelMapper.map(testModel, Model.class);
        System.out.println(map.toString());
        Assertions.assertEquals(
                1L,
                map.getId()
        );
        Assertions.assertEquals(
                1L,
                map.getUserId()
        );
    }

    @Data
    public static class Model{
        private long id;

        private String userId;
    }

    @Data
    public static class TestModel{
        private int userId;
    }
}

上記の事象を防ぐために

        modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
        modelMapper.getConfiguration().setFullTypeMatchingRequired(true);

を設定しましょう。厳密なプロパティ名、厳密な型のmappingをします。