Polymorphic Mapping Issue - Does ModelMapper support this?

1,314 views
Skip to first unread message

Ken Egervari

unread,
Oct 17, 2013, 7:42:22 PM10/17/13
to model...@googlegroups.com

I am using ModelMapper for Java, and it's a nifty, simple tool for doing Domain Object -> DTO mapping.

Let's say I have a DTO like this:

public class TestDTO {

    List<QuestionDTO> questions;

    // gettings and setters

}

With ModelMapper, I am trying to map a Test object that contains a List<Question> to TestDTO.

The Question class in the Test class is abstract, so the individual instances in the list will be subclasses, such as ShortAnswerQuestion or MultipleChoiceQuestion.

How can I tell ModelMapper to create DTO's of types ShortAnswerQuestionDTO and MultipleChoiceQuestionDTO? By Default, ModelMapper is mapping them to QuestionDTO, since the list is defined that way... but that's not what I want.

If ModelMapper doesn't support this, do any of the mapping frameworks for Java support it? Or is this something I am going to have to do by hand?


Thanks!

Jonathan Halterman

unread,
Oct 17, 2013, 8:20:45 PM10/17/13
to model...@googlegroups.com
Hi Ken,

Support for this doesn't exist yet. Right now there's just an outstanding issue. ModelMapper by default will construct the destination type that it reads from the property, QuestionDTO in this case. If you'd like it to construct something else the workaround for now is to use a Provider to take control of QuestionDTO construction.

As for other libraries, I believe Dozer does support something like this.

Cheers,
Jonathan

Ken Egervari

unread,
Oct 17, 2013, 8:46:11 PM10/17/13
to model...@googlegroups.com
Hi Jonathan,

Thanks so much for your quick response!

So, I tried to add a provider to the ModelMapper, just to try it out, like this:

        getConfiguration().setProvider(
            new Provider<QuestionDetailsDTO>() {
                @Override
                public QuestionDetailsDTO get(ProvisionRequest<QuestionDetailsDTO> questionDetailsDTOProvisionRequest) {
                    Object source = questionDetailsDTOProvisionRequest.getSource();

                    if(source instanceof ShortAnswerQuestion) {
                        return new ShortAnswerQuestionDetailsDTO();
                    } else if(source instanceof MultipleChoiceQuestion) {
                        return new MultipleChoiceQuestionDetailsDTO();
                    }

                    throw new IllegalStateException("question must be known type.");
                }
            }
        );

However, I don't see how to make ModelMapper only use this for `Question` classes. It seems to use it for everything. I suspected this might be the case, since there is no way to tell ModelMapper, use this when we want to go from Question to QuestionDetailsDTO.

How can I change this to make the work-around function as intended?

Thanks!

Jonathan Halterman

unread,
Oct 17, 2013, 11:31:44 PM10/17/13
to model...@googlegroups.com
There are a few different places you can set a Provider. Setting one against the ModelMapper's Configuration means that Provider is used globally to construct all destination types. To filter only the type you're interested in, check where questionDetailsDTOProvisionRequest.getRequestedType().equals(QuestionDTO.class) (or whatever).

You can also narrow the scope of your Provider down a bit by setting it on a specific TypeMap, either to provide instances of the destination type or its properties. You can also set a Provider on an individual property as part of a property mapping.

Cheers,
Jonathan


--
You received this message because you are subscribed to the Google Groups "modelmapper" group.
To unsubscribe from this group and stop receiving emails from it, send an email to modelmapper...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply all
Reply to author
Forward
0 new messages