Pippi
Pippi

Reputation: 323

Swagger with MapStruct throws org.springframework.context.annotation.ConflictingBeanDefinitionException

I'm trying to implement swagger2 in my project. (Spring Boot project) I've followed this guide

Then I've included swagger into pom.xml:

<spring.boot.version>2.1.4.RELEASE</spring.boot.version>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger2</artifactId>
  <version>${swagger.version}</version>
  <scope>compile</scope>
</dependency>
<dependency>
  <groupId>io.springfox</groupId>
  <artifactId>springfox-swagger-ui</artifactId>
  <version>${swagger.version}</version>
  <scope>compile</scope>
</dependency>

And I've created a @Configuration class

@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
}

Now when I start up the application, I get this error:

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [configuration.SwaggerConfig]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'licenseMapperImpl' for bean class [springfox.documentation.swagger2.mappers.LicenseMapperImpl] conflicts with existing, non-compatible bean definition of same name and class [data.mapper.LicenseMapperImpl]
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'licenseMapperImpl' for bean class [springfox.documentation.swagger2.mappers.LicenseMapperImpl] conflicts with existing, non-compatible bean definition of same name and class [data.mapper.LicenseMapperImpl]

LicenseMapperImpl is generated by MapStruct, and I dont understand how to solve this problem. I think a possible solution should be to add name to the compoment but mapstruct, but I've found this bug on his repository https://github.com/mapstruct/mapstruct/issues/1427.

ConflictingBeanDefinitionException should be thrown with existing, non-compatible bean definition of same name and class. But they shouldn't exist two bean of LicenseMapperImpl.class and LicenseMapperImpl.class is a simple component.

Here is LicenseMapperImpl.class:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2019-07-19T11:46:08+0200",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_181 (Oracle Corporation)"
)
@Component
public class LicenseMapperImpl implements LicenseMapper {

    @Override
    public License toEntity(LicenseDto dto) {
        // do something
    }

    @Override
    public LicenseDto toDto(License entity) {
       // do something
    }

    @Override
    public List<License> toEntity(List<LicenseDto> dtoList) {
       // do something
    }

    @Override
    public List<LicenseDto> toDto(List<License> entityList) {
      // do something
    }


}

EDIT

I've renamed LicenseMapper to LicenseServiceMapper and all work fine. I dont undestand how, if anyone can clear my mind I would be happy

Upvotes: 3

Views: 2490

Answers (3)

D.Tomov
D.Tomov

Reputation: 1158

Unrelated to swagger when I moved the mapper from one package to another, I got the same error. I fixed it by running mvn clean , or it can be fixed by just deleting already generated /target dir.

Upvotes: 0

Pippi
Pippi

Reputation: 323

resolved by renaming LicenseMapper to LicenseServiceMapper.

Upvotes: 0

CptDayDreamer
CptDayDreamer

Reputation: 1794

I'm also not sure why this happens but I found a simple solution for our project:

@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE, implementationName = "test")
public interface ModelMapper {

    ModelMapper INSTANCE = Mappers.getMapper(ModelMapper.class);

    @Mapping(target = "lastUpdated", source = "time")
    Model modelDtoToEntity(ModelDto modelDto);

    @Mapping(target = "time", source = "lastUpdated")
    ModelDto entityToModelDto(Model model);

}

I've just added the attribute implementationName and gave it a custom name (here implementationName = "test"). I also tried renaming like you said but that did not fix it for me.

I'm using MapStruct 1.3.1.Final and Swagger 3.0.0 with Gradle

Upvotes: 2

Related Questions