Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to configure Orika classMap for class hierarchies?

I'm trying to understand how to configure Orika class mapping correctly in case I have inheriting classes.

I've set up a simple example to ba able to understand what is working and what is not working, but I do not get it.

public class Source {
    private final String alpha;

    public Source(final String alpha) {
        this.alpha = alpha;
    }

    public String getAlpha() {
        return alpha;
    }
}


public final class SourceExtended extends Source {
    private final String beta;

    public SourceExtended(final String alpha, final String beta) {
        super(alpha);
        this.beta = beta;
    }

    public String getBeta() {
        return beta;
    }
}


public final class Target {
    private final String alpha;
    private final String beta;

    public Target (final String alpha) {
        this(alpha, null);
    }

    public Target(final String alpha, final String beta) {
        this.alpha = alpha;
        this.beta = beta;
    }

    public String getAlpha() {
        return alpha;
    }

    public String getBeta() {
        return beta;
    }
}

I'm doing the mapping as follows

    Source s = new Source("alpha");
    Target t = this.mapper.map(s, Target.class);


    SourceExtended s = new SourceExtended("alpha", "beta");
    Target t = this.mapper.map(s, Target.class);

And I have tried the following configurations...

factory.classMap(SourceExtended.class, Target.class)
    .byDefault()
    .register();

factory.classMap(Source.class, Target.class)
    .byDefault()
    .register();

Result: Both mappings compile and run, but beta is not set in the target for the SourceExtended object, so the mapping for SourceExtended is not working.

So I thought that if I explicitly state the constructor to be used, then beta should be mapped too:

factory.classMap(SourceExtended.class, Target.class)
    .byDefault()
    .constructorA("alpha", "beta")
    .constructorB("alpha", "beta")
    .register();

factory.classMap(Source.class, Target.class)
    .byDefault()
    .register();

But it the result is the same. beta is not mapped. And it does not change if I replace the default mapping by specifying the fields or by adding also the constructor to the mapping configuration of Source.class.

Can anyone give me a hint how to configure such a mapping? Thanks!

Kind regards, jose

like image 768
jose Avatar asked Jun 23 '14 14:06

jose


1 Answers

Yep, you can use ClassMapBuilder.use that will automatically use existing mappings on parent classes.

Here I already had existing mapping from TicketEntity to Conversation and I want to map it to new DetailedConversation (that has extra fields) and I did it like so:

    mapperFactory.classMap(TicketEntity.class, DetailedConversation.class)
            .use(TicketEntity.class, Conversation.class)
            .customize(conversationMapper())
            .byDefault()
            .register();
like image 119
Xorty Avatar answered Oct 18 '22 05:10

Xorty