web-dev-qa-db-ja.com

MapStructにはImplクラスが必要です

次のクラスがあります:

マッパー

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;
    }
}

そして、このマッピングを使用するspring serviceクラスのメソッド:

@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

では、なぜマッパーに実装クラスが必要なのでしょうか。誰かがアドバイスしてくれませんか?ありがとう。

11
Iurii

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

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

13
Gunnar

mavenを使用する場合は、次のようにmapstruct-processor依存関係を追加する必要があります。

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.2.0.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.2.0.Final</version>
</dependency>
17
Lê văn Huy

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

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

12
dplavcic

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>
5
Omtara

Mapstructと一緒にProject lombokを使用している場合は、両方がコンパイル時にソースを生成するため、Mavenコンパイラプラグインで両方を構成する必要があります。

        <plugins>
            <plugin>
                <groupId>org.Apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${Java.version}</source>
                    <target>${Java.version}</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
2

私のプロジェクトでは、gradleを使用して同じ問題に遭遇しました。そして、build.gradelから

compile 'org.mapstruct:mapstruct:1.2.0.CR2'

compile 'org.mapstruct:mapstruct-jdk8:1.1.0.Final'
compile 'org.mapstruct:mapstruct-processor:1.1.0.Final'

次に、sh&clean&buildをビルドします。それは今動作します!

2
Wentao Wan

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

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

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

1
sh87

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を追加

0
FBH

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

また、./gradlew clean build -x testは機能すると思いますが、すべてのテストを実行できるわけではありません。

0
James