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;
}
}
и способ от источников класс, где я использую это сопоставление:
@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] в контексте с path [] бросил обработчик исключений ошибка обработки; вложенное исключение Ява.ленг.ExceptionInInitializerError] с первопричиной Ява.ленг.ClassNotFoundException: dto.DeviceTokensMapperImpl
так почему mapper требует класса реализации? Может, кто-нибудь посоветует? Спасибо.
7 ответов
MapStruct генерирует код во время компиляции, и вызов Mappers.getMapper(DeviceTokensMapper.class);
будет искать сгенерированную реализацию интерфейса mapper. По какой-то причине он отсутствует в вашем подразделении развертывания (война и т. д.).
кстати. при работе с Spring в качестве контейнера DI вы можете использовать @Mapper(componentModel="spring")
и вы сможете получить экземпляры mapper с помощью инъекции зависимостей вместо использования Mappers
фабрики.
У вас есть как mapstruct-processor-xx и mapstruct-xx библиотеки, включенные в ваш проект?
У меня была такая же проблема, и я понял, что забыл включить mapstruct-processor-xx.
Если вы используете 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>
вы используете Maven? Если да, то, скорее всего, вы пропустили конфигурацию mapstruct-processor под плагином компилятора maven.
правильная конфигурация выглядит следующим образом:
<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>
теги для обхода ошибки eclipse (Mars) следующим образом
<pluginManagement>
<plugin> ... </plugin>
</pluginManagement>
удаление <pluginManagement>
теги исправили это для меня.
я столкнулся с той же проблемой в моем проекте с gradle. И я заменяю 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'
затем sh build clean & build. Теперь работает!
я столкнулся с этой проблемой, потому что я не запустить ./gradlew clean build
(gradlew.bat
для Windows) после создания / редактирования класса mapper или связанных классов.
кроме того, то, что я нашел, было полезно ./gradlew clean build -x test
работает, но не запускает весь ваш тест, что было много в моем случае.