web-dev-qa-db-fra.com

MapStruct - L'annotation @Mapper ne crée pas de bean

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.

8
Kutti

J'ai résolu l'erreur en faisant

  1. mvn clean install
  2. 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>
    
8
Kshitiz Lohia

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')
2
Snuf

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.

1
Max Vorontsov

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.

1
Adrian Elder

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 springcomponentModel 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)

0
Filip

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.

0
Bhaumik Thakkar