19

次のクラスがあります:

マッパー

public interface DeviceTokensMapper {

    DeviceTokensMapper INSTANCE = Mappers.getMapper(DeviceTokensMapper.class);

    @Mappings({
            @Mapping(source = "tokenName", target = "tokenName"),
            @Mapping(source = "userOsType", target = "osType"),
    })

    DeviceTokensDTO toDeviceTokensDTO(DeviceTokens deviceTokens);
}

実在物:

@Entity
public class DeviceTokens {

    @Id
    @Column(name="token_name", nullable = false)
    private String tokenName;

    @Column(name = "os", nullable = false)
    @Enumerated
    private UserOSType userOsType;

    public DeviceTokens() {}

    public DeviceTokens(String tokenName, UserOSType userOSType) {
        this.tokenName = tokenName;
        this.userOsType = userOSType;
    }

    public String getTokenName() {
        return tokenName;
    }

    public void setTokenName(String tokenName) {
        this.tokenName = tokenName;
    }

    public UserOSType getUserOsType() {
        return userOsType;
    }

    public void setUserOsType(UserOSType userOsType) {
        this.userOsType = userOsType;
    }
}

DTO:

public class DeviceTokensDTO {

    private String tokenName;

    private UserOSType osType;

    public DeviceTokensDTO() {}

    public DeviceTokensDTO(String tokenName, UserOSType osType) {
        this.tokenName = tokenName;
        this.osType = osType;
    }

    public UserOSType getOsType() {
        return osType;
    }

    public void setOsType(UserOSType osType) {
        this.osType = osType;
    }

    public String getTokenName() {
        return tokenName;
    }

    public void setTokenName(String tokenName) {
        this.tokenName = tokenName;
    }
}

そして、このマッピングを使用するスプリング サービスクラスのメソッド:

@Transactional
public DeviceTokensDTO storeToken(String tokenId, UserOSType userOsType) {
    DeviceTokens deviceTokens = new DeviceTokens(tokenId, userOsType);
    DeviceTokens newDevice = deviceTokensRepository.save(deviceTokens);

    return DeviceTokensMapper.INSTANCE.toDeviceTokensDTO(newDevice);
}

上記のメソッドを実行すると、次の例外が表示されます。

エラー [dispatcherServlet]:? - サーブレット [dispatcherServlet] の Servlet.service() がパス [] のコンテキストで例外をスローしました [ハンドラーの処理に失敗しました。ネストされた例外は java.lang.ExceptionInInitializerError] であり、根本的な原因は java.lang.ClassNotFoundException: dto.DeviceTokensMapperImpl です

では、なぜマッパーは実装クラスを必要とするのでしょうか? 誰かアドバイスをお願いできますか?ありがとう。

4

10 に答える 10

20

MapStruct はコンパイル時にコードを生成し、への呼び出しMappers.getMapper(DeviceTokensMapper.class);はマッパー インターフェイスの生成された実装を探します。何らかの理由で、展開ユニット (WAR など) に欠落しているようです。

ところで。Spring を DI コンテナーとして使用する場合は、ファクトリ@Mapper(componentModel="spring")を使用する代わりに依存性注入を使用してマッパー インスタンスを取得できます。Mappers

于 2015-08-12T13:37:05.457 に答える
13

プロジェクトに mapstruct-processor-xxmapstruct-xxライブラリの両方が含まれていますか?

同じ問題があり、mapstruct-processor-xx を含めるのを忘れていたことに気付きました。

于 2015-11-03T18:16:07.353 に答える
6

Mavenを使用していますか?はいの場合、おそらく maven コンパイラ プラグインの下で mapstruct-processor 構成を見逃しています。

適切な構成は次のとおりです。

<dependencies>
    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
        <version>${org.mapstruct.version}</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <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>
                        <version>${org.mapstruct.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>
于 2016-07-04T06:49:25.170 に答える
2

Mapper クラスで、次を使用します。@Mapper(componentModel = "spring")

mapstruct を使用して Impl クラスを生成するには、次の依存関係の両方が必要です。

        <!-- Dependencies for Mapper -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>
于 2020-07-02T04:10:39.687 に答える
2

build.gradle に追加

compile group: 'org.mapstruct',name: 'mapstruct-jdk8',version: 1.2.0.Final



annotationProcessor group: 'org.mapstruct',name: 'mapstruct-processor',version: 1.2.0.Final

設定で注釈処理を有効にする

おまけ: mapstruct のプラグイン intellij を追加

于 2018-12-07T10:16:33.030 に答える
1

私の場合、次のように日食(火星)のバグを回避するためにタグ<plugin>内にラップしていました<pluginManagement>

<pluginManagement>
 <plugin> ... </plugin> 
</pluginManagement>

タグを削除する<pluginManagement>と修正されました。

于 2016-09-08T02:17:49.723 に答える
0

マッパークラスまたは関連クラスを作成/編集した後./gradlew clean build( Windows 用) を実行しなかったため、この問題に遭遇しました。gradlew.bat

また、私が見つけた便利なものは./gradlew clean build -x test機能しますが、すべてのテストを実行するわけではありません。これは私の場合は多かったです。

于 2016-11-21T15:15:53.807 に答える