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.

+3


source to share


2 answers


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

.

+6


source


The @Autowired

class DeviceDataMapper

must be a Spring bean to work. It won't work if you create the instance yourself.



Either make it a Spring bean and use it as one, or pass a reference to deviceService

it from your controller.

+1


source







All Articles