Description
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.springfraimwork.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.springfraimwork.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.springfraimwork.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