J'ai téléchargé l'application depuis cette source https://github.com/springframeworkguru/spring5-mvc-rest/tree/vendor-api Et j'ai un problème avec MapStruct.
@Mapper
public interface CategoryMapper {
CategoryMapper INSTANCE = Mappers.getMapper(CategoryMapper.class);
CategoryDTO categoryToCategoryDTO(Category category);
}
@Data
public class CategoryDTO {
private Long id;
private String name;
}
classe de domaine:
@Data
@Entity
public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
Classe de service:
@Service
public class CategoryServiceImpl implements CategoryService {
private final CategoryMapper categoryMapper;
private final CategoryRepository categoryRepository;
public CategoryServiceImpl(CategoryMapper categoryMapper, CategoryRepository categoryRepository) {
this.categoryMapper = categoryMapper;
this.categoryRepository = categoryRepository;
}
}
Et dans la dépendance pom.xml, je n'en colle que deux ::
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<Java.version>1.8</Java.version>
<org.mapstruct.version>1.2.0.CR2</org.mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
Et plugin:
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</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>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
La description:
Parameter 0 of constructor in
guru.springfamework.services.CategoryServiceImpl required a bean of type 'guru.springfamework.api.v1.mapper.CategoryMapper' that could not be found.
Action:
Consider defining a bean of type 'guru.springfamework.api.v1.mapper.CategoryMapper' in your configuration.
Je pense que dans mon annotation Intellij @Mapper ne crée pas de bean pour mapper. Je n'ai pas changé le code de John GitHub. Une idée? J'ai essayé de changer la source générée par le chemin en cible, mais cela n'aide pas Merci pour l'aide.
J'ai résolu l'erreur en faisant
Ajoutez également ceci à votre pom
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</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>
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
</configuration>
</plugin>
J'ai eu le même problème. Dans Gradle, je l'ai résolu en ajoutant une nouvelle dépendance:
compileOnly('org.mapstruct:mapstruct-processor:1.3.0.Beta2')
Et toutes les dépendances nécessaires doivent être les suivantes:
compile('org.mapstruct:mapstruct:1.3.0.Beta2')
compileOnly('org.mapstruct:mapstruct-processor:1.3.0.Beta2')
annotationProcessor('org.mapstruct:mapstruct-processor:1.3.0.Beta2')
Pour utiliser les mappeurs comme beans et utiliser @Autowired
, Déclarez simplement les mappeurs comme @Mapper(componentModel = "spring")
. Il suffit ensuite de l'injecter là où vous en avez besoin.
Le problème est que l'utilisation de @Mapper
construct va générer une classe sans l'annotation @Component par défaut.
Vous n'utilisez probablement pas Maven pour compiler votre projet. Assurez-vous d'exécuter un Maven clean
et install
, ou passez les arguments du compilateur mapstruct.defaultComponentModel=spring
manuellement.
Puisque vous utilisez:
<compilerArgs>
<compilerArg>
-Amapstruct.defaultComponentModel=spring
</compilerArg>
</compilerArgs>
Cela indiquera à MapStruct
de générer un Spring Component
.
Si vous vérifiez votre classe cible compilée et l'ouvrez dans un décompilateur (si votre IDE le supporte), il devrait y avoir un CategoryMapperImpl
annoté avec @Component.
Je suppose que cela ne fonctionne pas uniquement dans IntelliJ. Il existe un problème connu, où IntelliJ ne récupère pas les processeurs d'annotation du compilateur maven annotationProcessorPaths
(voir IDEA-150621 pour plus d'informations).
De plus, les exemples du référentiel lié sont contraires aux meilleures pratiques de MapStruct. Lorsque spring
componentModel
est utilisé, alors Mappers.getMapper
ne doit jamais être utilisé. La raison en est que l'usine ne sera pas en mesure de construire correctement le mappeur car il doit être construit via un ressort. L'argument du compilateur mapstruct.defaultComponentModel
peut interrompre l'intégration avec IDE, car il n'est pas récupéré (vous devrez également le définir dans les paramètres IntelliJ)
Vous devez activer votre processeur d'annotation dans votre IntelliJ à partir de,
Paramètres -> Build, Execution, Deployment -> Compiler -> Annotation Processors et cliquez sur la case à cocher Enable Annotation processing.