Skip to content

Mapping with source parameter in Mapping#source ignored on inner objects when another mapping is specified #2322

Description

@tiller

Hello,
I'm not entirely sure this is a bug as the use of source="." doesn't seem to be documented, but here it is anyway.

Considering the following example:

public class A {
    public int field1A;
    public int field2;
    public int field3;
}

class B {
    public int field1B;
    public int field2;
    public int field3;
}

class Wrap {
    public B b;
}

@Mapper
interface MapInner {

    // @Mapping(source = "field1A", target = "b.field1B")
    @Mapping(source = ".", target = "b")
    Wrap map(A a);
}

@Mapper
interface MapDirect {

    // @Mapping(source = "field1A", target = "field1B")
    @Mapping(source = ".", target = ".")
    B map(A a);
}

The resulting mapping does bind field2 and field3 automatically, both for the direct A->B mapping and the A->Wrap(B)

class MapInnerImpl implements MapInner {
    [...]
    protected B aToB(A a) {
        [...]
        B b = new B();

        b.field2 = a.field2;
        b.field3 = a.field3;

        return b;
    }
}

class MapDirectImpl implements MapDirect {

    @Override
    public B map(A a) {
        [...]
        B b = new B();

        b.field2 = a.field2;
        b.field3 = a.field3;

        return b;
    }
}

However, when uncommenting the annotation that gives special instructions for an unmapped field, mapstruct no longer maps field2 and field3 for the A->Wrap(B) mapping but does it perfectly for the A->B mapping

class MapInnerImpl implements MapInner {
    [...]
    protected B aToB(A a) {
        [...]
        B b = new B();

        b.field1B = a.field1A;

        return b;
    }
}


class MapDirectImpl implements MapDirect {

    @Override
    public B map(A a) {
        [...]
        B b = new B();

        b.field1B = a.field1A;
        b.field2 = a.field2;
        b.field3 = a.field3;

        return b;
    }
}

I'm using version 1.4.1.Final

Note: working workaround is to use:

@Mapper
interface MapInner {
    @Mapping(source = ".", target = "b")
    Wrap map(A a);

    @Mapping(source = "field1A", target = "field1B")
    @Mapping(source = ".", target = ".")
    B intermediateMap(A a);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions