MapStruct 需要 Impl class
MapStruct requires Impl class
我有下一个 classes:
映射器
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 服务 class 的方法,我在其中使用此映射:
@Transactional
public DeviceTokensDTO storeToken(String tokenId, UserOSType userOsType) {
DeviceTokens deviceTokens = new DeviceTokens(tokenId, userOsType);
DeviceTokens newDevice = deviceTokensRepository.save(deviceTokens);
return DeviceTokensMapper.INSTANCE.toDeviceTokensDTO(newDevice);
}
当我 运行 以上方法时,我看到下一个异常:
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
那么为什么 mapper 需要实现 class?可以请人指教吗?
谢谢。
MapStruct 在编译时生成代码,对Mappers.getMapper(DeviceTokensMapper.class);
的调用将查找映射器接口的生成实现。由于某种原因,您的部署单元中似乎缺少它(WAR 等)。
顺便说一句。当使用 Spring 作为您的 DI 容器时,您可以使用 @Mapper(componentModel="spring")
并且您将能够通过依赖注入而不是使用 Mappers
工厂来获取映射器实例。
您的项目中是否包含 mapstruct-processor-xx 和 mapstruct-xx 库?
我遇到了同样的问题,我意识到我忘记包含 mapstruct-processor-xx。
你在使用 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>
在我的例子中,我将 <plugin>
包装在 <pluginManagement>
标签中,以解决日食(火星)错误,如下所示
<pluginManagement>
<plugin> ... </plugin>
</pluginManagement>
删除 <pluginManagement>
标签为我修复了它。
我 运行 遇到这个问题是因为我没有 运行 ./gradlew clean build
(gradlew.bat
for Windows)在 creating/editing 映射器之后class 或相关 classes.
此外,我发现有用的东西是 ./gradlew clean build -x test
有效,但 运行 不是你所有的测试,这对我来说是很多。
我在 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 build clean&build。现在可以使用了!
如果使用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>
在您的 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
如果您同时使用 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>
在您的映射器 class 中,使用 @Mapper(componentModel = "spring")
并使用 mapstruct 生成 Impl classes,您需要以下两个依赖项。
<!-- 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>
我有下一个 classes:
映射器
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 服务 class 的方法,我在其中使用此映射:
@Transactional
public DeviceTokensDTO storeToken(String tokenId, UserOSType userOsType) {
DeviceTokens deviceTokens = new DeviceTokens(tokenId, userOsType);
DeviceTokens newDevice = deviceTokensRepository.save(deviceTokens);
return DeviceTokensMapper.INSTANCE.toDeviceTokensDTO(newDevice);
}
当我 运行 以上方法时,我看到下一个异常:
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
那么为什么 mapper 需要实现 class?可以请人指教吗? 谢谢。
MapStruct 在编译时生成代码,对Mappers.getMapper(DeviceTokensMapper.class);
的调用将查找映射器接口的生成实现。由于某种原因,您的部署单元中似乎缺少它(WAR 等)。
顺便说一句。当使用 Spring 作为您的 DI 容器时,您可以使用 @Mapper(componentModel="spring")
并且您将能够通过依赖注入而不是使用 Mappers
工厂来获取映射器实例。
您的项目中是否包含 mapstruct-processor-xx 和 mapstruct-xx 库?
我遇到了同样的问题,我意识到我忘记包含 mapstruct-processor-xx。
你在使用 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>
在我的例子中,我将 <plugin>
包装在 <pluginManagement>
标签中,以解决日食(火星)错误,如下所示
<pluginManagement>
<plugin> ... </plugin>
</pluginManagement>
删除 <pluginManagement>
标签为我修复了它。
我 运行 遇到这个问题是因为我没有 运行 ./gradlew clean build
(gradlew.bat
for Windows)在 creating/editing 映射器之后class 或相关 classes.
此外,我发现有用的东西是 ./gradlew clean build -x test
有效,但 运行 不是你所有的测试,这对我来说是很多。
我在 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 build clean&build。现在可以使用了!
如果使用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>
在您的 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
如果您同时使用 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>
在您的映射器 class 中,使用 @Mapper(componentModel = "spring")
并使用 mapstruct 生成 Impl classes,您需要以下两个依赖项。
<!-- 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>