Issue
I am having below mapper class in which I want to use CounterService
. I am trying constructor injection but that's not working and null
is printing.
@Mapper(componentModel = "spring", uses = CounterService.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class CarMapper {
private CounterService counterService;
public CarMapper(CounterService counterService) {
this.counterService = counterService;
}
public abstract Car dtoToEntity(CarDto carDto);
public CarDto entityToDto(Car car) {
System.out.println(counterService)
//....
return carDto;
}
}
Implementation class by mapStruct
@Component
public class CarMapperImpl extends CarMapper{
@Override
public Car dtoToEntity(CarDto carDto){
//...
}
}
If I use field injection using @AutoWired
, that way it works fine. It means Spring doesn't support the constructor injection of abstract
class. Is it because abstract
class can't be instantiated directly and require a subclass to instantiate?
Is there any way mapStruct
can create a constructor inside the implementation class as:
public CarMapperImpl(CounterService counterService){
super(counterService);
}
That way, constructor injection should work.
Solution
This has nothing to do with Spring. It was a deliberate decision done by the MapStruct team to not use super constructors.
What you can do though is to use setter injection.
@Mapper(componentModel = "spring", uses = CounterService.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class CarMapper {
private CounterService counterService;
public abstract Car dtoToEntity(CarDto carDto);
public CarDto entityToDto(Car car) {
System.out.println(counterService)
//....
return carDto;
}
@Autowired
public void setCounterService(CounterService counterService) {
this.counterService = counterService;
}
}
Answered By - Filip
Answer Checked By - Pedro (JavaFixing Volunteer)