bugfix> spring-boot > 投稿

SpringとKotlinのプロジェクトでMapstructを使用する方法を学んでいます。

リストを含む生成されたDTO(ThessaurusDTO)があり、これをモデル(Vocab)のリストにマップする必要があります。

MapStructがこれを自動的にマップできないことは理にかなっていますが、最初のリストは常にサイズ= 1になることを知っています。DTOモデルが属するAPIを制御できません。 で見つけたドキュメンテーション インターフェイス内でデフォルトのメソッド実装を定義することを作成できます。これは、Kotlinの通常の関数に大まかに変換されます。

私のマッパーインターフェイス:

@Mapper
interface VocabMapper {
    @Mappings(
            // ...
    )
    fun thessaurusToVocab(thessaurusDTO: ThessaurusDTO): Vocab
    fun metaSyns(nestedList: List<List<String>>): List<String> 
             = nestedList.flatten()
}

ビルドを実行しようとすると、次のエラーが発生します。

VocabMapper.java:16: error: Can't map collection element "java.util.List<java.lang.String>" to "java.lang.String ". Consider to declare/implement a mapping method: "java.lang.String map(java.util.List<java.lang.String> value)".

私のカスタム実装を無視している間、mapStructはまだ自動的にマッピングを試みているようです。私はここで些細なことを見逃していますか?

回答 2 件
  • I found on the documentation that I can create define a default method implementation within the interface, which would loosely translate to a normal function in Kotlin

    From my understand of what I found online, Kotlin does not properly translate an interface function into a default method in Java, but actually generates a class that implements the interface.

    それが問題である場合は、注釈を付けることができます metaSyns@JvmDefault

    Specifies that a JVM default method should be generated for non-abstract Kotlin interface member.

    Usages of this annotation require an explicit compilation argument to be specified: either -Xjvm-default=enable または -Xjvm-default=compatibility

    違いについてはリンクを参照してくださいが、おそらく必要です -Xjvm-default=enable

  • インターフェイスを使用する代わりに、抽象ベースの実装に依存することでこれを修正したことを確認しました。 オンラインで見つけたものを理解したところ、Kotlinはインターフェイス関数をJavaのデフォルトのメソッドに適切に変換しませんが、実際にはインターフェイスを実装するクラスを生成します。

    https://github.com/mapstruct/mapstruct/issues/1577

あなたの答え