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
MapStruct requires Impl class
提问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 Mappers
factory.
顺便提一句。当使用 Spring 作为你的 DI 容器时,你可以使用@Mapper(componentModel="spring")
并且你将能够通过依赖注入而不是使用Mappers
工厂来获取映射器实例。
回答by dplavcic
Do you have both mapstruct-processor-xxand mapstruct-xxlibraries included in your project?
您的项目中是否同时包含 mapstruct-processor-xx和mapstruct-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.bat
for Windows) after creating/editing the mapper class or related classes.
我遇到了这个问题,因为我在创建/编辑映射器类或相关类后没有运行./gradlew clean build
(gradlew.bat
对于 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
有效的,但不能运行所有的测试,这对我来说很多。
回答by Wentao Wan
I have met the same problem in my project with gradle. And I replace the build.gradel
from
我在我的 gradle 项目中遇到了同样的问题。我替换了build.gradel
from
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>