简体   繁体   English

MapStruct 需要 Impl 类

[英]MapStruct requires Impl class

I have next classes:我有下一节课:

Mapper映射器

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:实体:

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

And method from spring service class where I use this mapping:以及我使用此映射的spring 服务类的方法:

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

    return DeviceTokensMapper.INSTANCE.toDeviceTokensDTO(newDevice);
}

When I run above method I see next exception:当我运行上述方法时,我看到下一个异常:

ERROR [dispatcherServlet]:?错误 [dispatcherServlet]:? - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler processing failed; - servlet [dispatcherServlet] 的 Servlet.service() 在路径为 [] 的上下文中抛出异常 [处理程序处理失败; nested exception is java.lang.ExceptionInInitializerError] with root cause java.lang.ClassNotFoundException: dto.DeviceTokensMapperImpl嵌套异常是 java.lang.ExceptionInInitializerError] 其根本原因 java.lang.ClassNotFoundException: dto.DeviceTokensMapperImpl

So why mapper require implementation class?那么为什么映射器需要实现类呢? Could please someone advise?可以请人指教吗? Thanks.谢谢。

if you use maven, you need to add mapstruct-processor dependency as follows:如果使用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>

MapStruct generates code at compile time, and the call to Mappers.getMapper(DeviceTokensMapper.class); MapStruct 在编译时生成代码,并调用Mappers.getMapper(DeviceTokensMapper.class); will look for the generated implementation of the mapper interface.将查找映射器接口的生成实现。 For some reason it seems to be missing in your deployment unit (WAR etc.).出于某种原因,您的部署单元(WAR 等)中似乎缺少它。

Btw.顺便提一句。 when working with Spring as your DI container, you can use @Mapper(componentModel="spring") and you will be able to obtain mapper instances via dependency injection instead of using the Mappers factory.当使用 Spring 作为您的 DI 容器时,您可以使用@Mapper(componentModel="spring")并且您将能够通过依赖注入而不是使用Mappers工厂来获取映射器实例。

Do you have both mapstruct-processor-xx and mapstruct-xx libraries included in your project?您的项目中是否同时包含 mapstruct-processor-xxmapstruct-xx库?

I had the same problem and I realized that I forgot to include mapstruct-processor-xx.我遇到了同样的问题,我意识到我忘记包含 mapstruct-processor-xx。

Are you using Maven?你在使用 Maven 吗? If yes, then most probably you have missed the mapstruct-processor configuration under the maven compiler plugin.如果是,那么您很可能错过了 maven 编译器插件下的 mapstruct-processor 配置。

The proper configuration is as follows:正确的配置如下:

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

I have met the same problem in my project with gradle.我在我的 gradle 项目中遇到了同样的问题。 And I replace the build.gradel from我更换build.gradel

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

to

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

Then sh build clean&build.然后 sh build clean&build。 It works now!它现在有效!

If you are using Project lombok along with mapstruct then you will need to configure both under maven compiler plugin, as both of them generate source at compile time.如果您将 Project lombok 与 mapstruct 一起使用,那么您需要在 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>

In your build.gradle add在你的 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

Enable annotation Processing in your setting在您的设置中启用注释处理

Bonus : add plugin intellij for mapstruct奖励:为 mapstruct 添加插件 intellij

In my case I had wrapped <plugin> within <pluginManagement> tags to workaround an eclipse (Mars) bug as follows就我而言,我将<plugin>包裹在<pluginManagement>标签中以解决日食(Mars)错误,如下所示

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

Removing <pluginManagement> tags fixed it for me.删除<pluginManagement>标签为我修复了它。

In your Mapper class, use @Mapper(componentModel = "spring")在您的 Mapper 类中,使用@Mapper(componentModel = "spring")

and to generate Impl classes using mapstruct, you need both of following dependencies.要使用 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>

I ran into this problem because I didn't run ./gradlew clean build ( gradlew.bat for Windows) after creating/editing the mapper class or related classes.我遇到了这个问题,因为我在创建/编辑映射器类或相关类后没有运行./gradlew clean build ( gradlew.bat for Windows )。

Also, something I found was useful is ./gradlew clean build -x test works, but doesn't run all your test, which was a lot in my case.另外,我发现有用的东西是./gradlew clean build -x test有效,但并没有运行所有的测试,这在我的情况下很多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM