Converting DTO to Entity Subclass
<p>My current situation is that I have an <code>abstract</code> model, in which many other models inherit from. The API consumes a "DTO" object, that is essentially one big object that contains all of the possible fields for each subclass, due to the client calling the service. I've created a solution for this, but it feels like it has some bad "smells". Here is an example of the setup:</p>

<pre><code>public abstract class Person {
    public Long id;
    public Long name;
}

public class Employee extends Person {
    public Date startDate;
}

public class Student extends Person {
    public Double gpa;
}

public class PersonDTO {
    public Long id;
    public String name;
    public Date startDate;
    public Double gpa;
    public String type;
}
</code></pre>

<p>I want to convert the DTO to its concrete subclass with initialization. I've solved that by creating a factory and overriding a method in each of the subclasses:</p>

<pre><code>public class PersonFactory {

    public Person getInstance(String type) {
        if (type.equals("Student")) {
            return new Student();
        } else if (type.equals("Employee")) {
            return new Employee();
        }

        return null;
    }
}

public class Student extends Person {

    public Double gpa;

    /**
     * Initializes the additional fields in the subclass
     * from the PersonDTO.
     */
    @Override
    public void initialize(PersonDTO dto) {
        this.gpa = dto.gpa;
    }
}
</code></pre>

<p>So the calling class will do the following:</p>

<pre><code>public Person createPerson(PersonDTO dto) {
    Person person = new PersonFactory().getInstance(dto.type);
    person.name = dto.name;
    person.id = dto.id;
    person.initialize(dto);
}
</code></pre>

<p>To put this into perspective a little more, the model superclass (in this example, <code>Person</code>) has about 15 fields, and the subclasses can have up to 5 or 6, making using a constructor cumbersome. I feel like having the <code>initialize</code> method is a bad practice, and couples the Person class to the DTO class (this also violates the <a href="https://en.wikipedia.org/wiki/Law_of_Demeter" rel="nofollow">Law of Demeter</a>).</p>

<p>Ideally, I'd like to create a <code>Mapper</code> or <code>Translator</code> class, that will translate the DTO into the concrete subclass, but I keep running into the following issue with initializing the common fields:</p>

<pre><code>public class PersonMapper implements Mapper&lt;PersonDTO, Person&gt; {

    public Person map(PersonDTO dto) {
        if (dto.type.equals("Student")) {
            Student person = new Student();
            setupCommonFields(person, dto);   // required to call this method
            person.gpa = dto.gpa;             // inside of every block
            return person;
        } else if (dto.type.equals("Employee")) {
            Employee person = new Employee();
            setupCommonFields(person, dto);
            person.startDate = dto.startDate;
            return person;
        }
    }

    private void setupCommonFields(Person person, PersonDTO dto) {
        person.id = dto.id;
        person.name = dto.name;
    }
}
</code></pre>

<p>This seems like a clearly simple problem to solve, but I can't seem to come up with the most perfect solution. Is there a better-designed solution for this?</p>