I'd like to use mapstruct to deepclone same objects. However situation is little bit trickier as I'm using abstraction.
public abstract class Fruit {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
public class Banana extends Fruit {
private String origin;
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
}
public class Apple extends Fruit {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
@Mapper(mappingControl = DeepClone.class, subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION)
public interface FruitMapper {
@SubclassMapping(source = Apple.class, target = Apple.class)
@SubclassMapping(source = Banana.class, target = Banana.class)
Fruit clone(Fruit fruit);
}
and finally this is what is generated:
public class FruitMapperImpl implements FruitMapper {
@Override
public Fruit clone(Fruit fruit) {
if ( fruit == null ) {
return null;
}
if (fruit instanceof Apple) {
return (Apple) fruit;
}
else if (fruit instanceof Banana) {
return (Banana) fruit;
}
else {
throw new IllegalArgumentException("Not all subclasses are supported for this mapping. Missing for " + fruit.getClass());
}
}
}
The thing I'm missing is the actual implementation of given subclasses. Is that a bug or is it designed like this?
Because if I add method like Apple clone(Apple apple); then it should be good (for Apple only) however I don't see any benefit of adding SubclassMapping
public class FruitMapperImpl implements FruitMapper {
@Override
public Fruit clone(Fruit fruit) {
if ( fruit == null ) {
return null;
}
if (fruit instanceof Apple) {
return clone( (Apple) fruit );
}
else if (fruit instanceof Banana) {
return (Banana) fruit;
}
else {
throw new IllegalArgumentException("Not all subclasses are supported for this mapping. Missing for " + fruit.getClass());
}
}
@Override
public Apple clone(Apple apple) {
if ( apple == null ) {
return null;
}
Apple apple1 = new Apple();
apple1.setId( apple.getId() );
apple1.setType( apple.getType() );
return apple1;
}
}
EDIT: issue created