Skip to content

Support @AnnotatedWith on decorators #3659

Description

@rgcv

Expected behavior

When trying to use @AnnotatedWith to annotate a mapper implementation class with Spring's @ConditionalOnProperty on a @DecoratedWith mapper

@Mapper(componentModel = "spring")
@AnnotatedWith(value = ConditionalOnProperty.class, elements = {
    @Element(name = "name", strings = "Property"),
    @Element(name = "havingValue", strings = "")
})
@DecoratedWith(Decorator.class)
interface MyMapper { }

Mapstruct correctly annotates the Impl_ class

@Generated(/* ... */)
@Component
@ConditionalOnProperty(
    name = "Property",
    havingValue = ""
)
@Qualifier("delegate")
public class MapperImpl_ { }

I was also expecting that the Decorator's base component class would be annotated

@Generated(/* ... */)
@Component
@ConditionalOnProperty(
    name = "Property",
    havingValue = ""
)
@Primary
public class MapperImpl extends Decorator { }

Actual behavior

Base implementation component is not annotated

@Generated(/* ... */)
@Component
@Primary
public class MapperImpl extends Decorator { }

This leads to a runtime error where, if I try to inject a mapper instance, it will fail providing a bean for MapperImpl since the delegate is conditional.

2024-08-09T11:26:29.123+01:00  WARN 44711 --- [mcve] [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mapstructAwApplicat
ion': Unsatisfied dependency expressed through field 'mapper': No qualifying bean of type 'com.example.mapstructaw.MyMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
2024-08-09T11:26:29.126+01:00  INFO 44711 --- [mcve] [           main] .s.b.a.l.ConditionEvaluationReportLogger :

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-08-09T11:26:29.130+01:00 ERROR 44711 --- [mcve] [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

Field mapper in com.example.mapstructaw.MapstructAwApplication required a bean of type 'com.example.mcve.MyMapper' that could not be found.

The injection point has the following annotations:
        - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean of type 'com.example.mapstructaw.MyMapper' in your configuration.

Steps to reproduce the problem

This should be enough to reproduce the issue in a plain spring boot starter project

@Mapper(componentModel = "spring")
@AnnotatedWith(value = ConditionalOnProperty.class, elements = {
        @Element(name = "name", value = "Property"),
        @Element(name = "havingValue", value = ""),
})
@DecoratedWith(Decorator.class)
interface MyMapper { }
abstract class Decorator implements MyMapper { }
@SpringBootApplication
public class McveApplication {
    @Autowired MyMapper mapper;

    public static void main(String[] args) {
        SpringApplication.run(McveApplication.class, args);
    }
}

MapStruct Version

1.6.0.RC1

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions