ModelMapper: Choose mapping based on Child class

Well, the solution I found uses converters. In this case modelMapper doesn't try to create a new instance of abstract class, but uses the converter directly.

You can put all the converters in same place

modelMapper.createTypeMap(ChildA.class, ParentDTO.class)
            .setConverter(mappingContext -> modelMapper.map(mappingContext.getSource(), ClassADTO.class));

modelMapper.createTypeMap(ChildB.class, ParentDTO.class)
            .setConverter(mappingContext -> modelMapper.map(mappingContext.getSource(), ClassBDTO.class));
....

I would use ObjectMapper instead of ModelMapper.

In Parent class add the possibility to get the discriminator value.

//..
public class Parent {

    @Column(name = "type", insertable = false, updatable = false)
    private String type;
    //getters and setters
}

Your ParentDTO should be mapped to Child(*)DTO

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = ChildADTO.class, name = "child_a"),
        @JsonSubTypes.Type(value = ChildBDTO.class, name = "child_b")
})
 public abstract class ParentDTO {
   // ..
 }

in the conversion service/method add an object mapper with ignore unknown (to ignore what you did not declare in your DTO class)

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

just simply call :

Parent parent = // get from repository
ParentDTO parentDTO = objectMapper.readValue(objectMapper.writeValueAsBytes(parent), ParentDTO.class);

In this way, your ParentDTO is always instantiated with the right type.