Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defined mappings for subclass mappings with runtime exception subclass exhaustive strategy not working if result type is abstract class #3331

Closed
xKrasusX opened this issue Jul 17, 2023 · 2 comments · Fixed by #3487
Assignees
Labels
Milestone

Comments

@xKrasusX
Copy link

xKrasusX commented Jul 17, 2023

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

@xKrasusX xKrasusX added the bug label Jul 17, 2023
@xKrasusX
Copy link
Author

Any updates on an issue? Is it correctly identified as a bug? If so, are there any plans to fix this?

@filiphr
Copy link
Member

filiphr commented Sep 10, 2023

Thanks for the detailed example @xKrasusX. I am fairly certain that the root cause for this issue is the same as #3360. We are going to look into it in the same time as we are fixing that one.

@filiphr filiphr added this to the 1.6.0 milestone Sep 10, 2023
@filiphr filiphr modified the milestones: 1.6.0.Beta1, 1.6.0.Beta2 Nov 4, 2023
filiphr added a commit to filiphr/mapstruct that referenced this issue Dec 27, 2023
…bstract due to runtime exception subclass exhaustive strategy
@filiphr filiphr self-assigned this Dec 27, 2023
thunderhook pushed a commit that referenced this issue Feb 11, 2024
…ue to runtime exception subclass exhaustive strategy (#3487)
@filiphr filiphr changed the title Abstract class fields mapping issues Defined mappings for subclass mappings with runtime exception subclass exhaustive strategy leads to compile error for the abstract class May 9, 2024
@filiphr filiphr changed the title Defined mappings for subclass mappings with runtime exception subclass exhaustive strategy leads to compile error for the abstract class Defined mappings for subclass mappings with runtime exception subclass exhaustive strategy not working if result type is abstract class May 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants