Java MapStruct 需要 Impl 类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31920934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 11:46:44  来源:igfitidea点击:

MapStruct requires Impl class

javaspringmapstruct

提问by Iurii

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 serviceclass 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]:? - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler processing failed; nested exception is java.lang.ExceptionInInitializerError] with root cause java.lang.ClassNotFoundException: dto.DeviceTokensMapperImpl

错误 [dispatcherServlet]:? - servlet [dispatcherServlet] 的 Servlet.service() 在路径为 [] 的上下文中抛出异常 [处理程序处理失败;嵌套异常是 java.lang.ExceptionInInitializerError] 其根本原因 java.lang.ClassNotFoundException: dto.DeviceTokensMapperImpl

So why mapper require implementation class? Could please someone advise? Thanks.

那么为什么映射器需要实现类呢?可以请人指教吗?谢谢。

采纳答案by Gunnar

MapStruct generates code at compile time, and the call to 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.).

MapStruct 在编译时生成代码,调用Mappers.getMapper(DeviceTokensMapper.class);将查找映射器接口的生成实现。出于某种原因,您的部署单元(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 Mappersfactory.

顺便提一句。当使用 Spring 作为你的 DI 容器时,你可以使用@Mapper(componentModel="spring")并且你将能够通过依赖注入而不是使用Mappers工厂来获取映射器实例。

回答by dplavcic

Do you have both mapstruct-processor-xxand mapstruct-xxlibraries 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。

回答by Omtara

Are you using Maven? If yes, then most probably you have missed the mapstruct-processor configuration under the maven compiler plugin.

你在使用 Maven 吗?如果是,那么您很可能错过了 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>

回答by sh87

In my case I had wrapped <plugin>within <pluginManagement>tags to workaround an eclipse (Mars) bug as follows

在我来说,我已经包裹<plugin><pluginManagement>标签要解决的日食(火星)错误如下

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

Removing <pluginManagement>tags fixed it for me.

删除<pluginManagement>标签为我修复了它。

回答by James

I ran into this problem because I didn't run ./gradlew clean build(gradlew.batfor Windows) after creating/editing the mapper class or related classes.

我遇到了这个问题,因为我在创建/编辑映射器类或相关类后没有运行./gradlew clean buildgradlew.bat对于 Windows)。

Also, something I found was useful is ./gradlew clean build -x testworks, but doesn't run all your test, which was a lot in my case.

另外,我发现有用的东西是./gradlew clean build -x test有效的,但不能运行所有的测试,这对我来说很多。

回答by Wentao Wan

I have met the same problem in my project with gradle. And I replace the build.gradelfrom

我在我的 gradle 项目中遇到了同样的问题。我替换了build.gradelfrom

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. It works now!

然后 sh build clean&build。它现在有效!

回答by Lê v?n Huy

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>

回答by FBH

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

回答by Rahul Bhooteshwar

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>