-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Expected behavior
Mapstruct can map fields of abstract classes
Actual behavior
Mapstruct is not mapping fields of abstract classes - various problems occur
Steps to reproduce the problem
Source classes:
public abstract class Vehicle {
private final String name;
Vehicle(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
public class Car extends Vehicle {
private final int numOfDoors;
Car(String name, int numOfDoors) {
super(name);
this.numOfDoors = numOfDoors;
}
public int getNumOfDoors() {
return numOfDoors;
}
}
public class Motorbike extends Vehicle {
private final boolean allowedForMinor;
Motorbike(String name, boolean allowedForMinor) {
super(name);
this.allowedForMinor = allowedForMinor;
}
public boolean isAllowedForMinor() {
return allowedForMinor;
}
}Target classes:
public abstract class VehicleDto {
private final String name;
public VehicleDto(String name) {
this.name = name;
}
}
public class CarDto extends VehicleDto {
private final int numOfDoors;
public CarDto(String name, int numOfDoors) {
super(name);
this.numOfDoors = numOfDoors;
}
}
public class MotorbikeDto extends VehicleDto {
private final boolean allowedForMinor;
public MotorbikeDto(String name, boolean allowedForMinor) {
super(name);
this.allowedForMinor = allowedForMinor;
}
}Mapper config:
@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION)
public interface VehicleMapper {
@SubclassMapping(target = CarDto.class, source = Car.class)
@SubclassMapping(target = MotorbikeDto.class, source = Motorbike.class)
VehicleDto mapToDto(Vehicle vehicle);
}Everything works fine so far, the mapper class is generated and mapping correctly all the fields.
The problem occurs when I'm trying to add anything related to name field in VehicleDto, for example:
@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION)
public interface VehicleMapper {
@SubclassMapping(target = CarDto.class, source = Car.class)
@SubclassMapping(target = MotorbikeDto.class, source = Motorbike.class)
@Mapping(target = "name", constant = "noname") // <-------- added this one --------
VehicleDto mapToDto(Vehicle vehicle);
}In this case I'm getting a compilation error:
Unknown property "name" in result type VehicleDto. Did you mean "null"?
If I also add getter to the abstract target class:
public abstract class VehicleDto {
private final String name;
public VehicleDto(String name) {
this.name = name;
}
public String getName() {
return name;
}
}It's still not working but the build error is different:
Property "name" has no write accessor in VehicleDto.
Isn't Mapstruct supposed to handle both these cases correctly and map the name field?
I'm using Java 17, Spring Boot 3.1.1, no Lombok.
MapStruct Version
1.5.5.Final