Autowiring inside an abstract class made for mapstruct
I am trying to create a REST controller using Spring. To format the data for readability and greater integration, I used Mapstruct. This is how I wrote the Mapper.
@Mapper
public abstract class DeviceDataMapper {
@Autowired
DeviceService deviceService;
public static DeviceDataMapper INSTANCE = Mappers.getMapper(DeviceDataMapper.class);
@Mappings({
@Mapping(source = "deviceId", target = "iddevice"),
@Mapping(source = "deviceName", target = "name")
})
public abstract TODevice deviceToTODevice(DeviceData device);
public DeviceData toDeviceToDeviceData(TODevice toDevice){
DeviceData deviceData = new DeviceData();
deviceData.setDeviceId(toDevice.getIddevice());
deviceData.setDeviceName(toDevice.getName());
deviceData.setDeviceTemplateId(toDevice.getDeviceTemplateId());
try {
deviceData.setDeviceTemplateName(deviceService.findDeviceTemplateById(toDevice.getDeviceTemplateId()).getName());
} catch (Exception e) {
e.printStackTrace();
}
return deviceData;
}}
The API controller function looks like this:
@RequestMapping(value = "/{deviceId}",method = RequestMethod.GET)
public @ResponseBody DeviceData get(@PathVariable int deviceId) {
DeviceData deviceData=new DeviceData();
try {
deviceData = DeviceDataMapper.INSTANCE.toDeviceToDevice(deviceService.findOne(deviceId));
} catch (Exception e) {
e.printStackTrace();
}
return deviceData;
}
The Data output returns fine except for one detail. I couldn't get to this function deviceService.findDeviceTemplateById(toDevice.getDeviceTemplateId()
(where deviceService is auto-connected). The error stack trace is showing me a NullPointerException. So I wonder if there is a general rule about the availability of offline resources in an abstract class? Or the way I am instantiating makes this function unavailable? What should I change to make it work? I have also tried with @Inject
from javax.inject
with the same result.
source to share
You can use Spring as a component model for a mapper:
@Mapper(componentModel="spring")
public abstract class DeviceDataMapper {
...
}
This way, you can inject dependencies into it (like other handwritten ones) and also inject into other mapper classes, rather than resorting to boilerplate INSTANCE
.
source to share