6

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

jose
  • 131
  • 1
  • 7

2 Answers2

9

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();
Xorty
  • 18,367
  • 27
  • 104
  • 155
  • 2
    Could you rewrite this to use his Objects? I can't find the documentation for the .use method on the Orika website... – markthegrea Sep 22 '16 at 14:10
0
factory.classMap(Parent.class, Parent.class).byDefault().register(); 
factory.classMap(ChildA.class, ChildA.class).byDefault().register();
factory.classMap(ChildB.class, ChildB.class).byDefault().register();
  • This may be a fine solution, but it really needs some explanation in order to be a useful answer. – Caleb Dec 05 '17 at 15:28