Any way to ignore methods for mapping method resolution?

1,489 views
Skip to first unread message

István Mészáros

unread,
Oct 25, 2019, 6:53:31 AM10/25/19
to mapstruct-users
Hello MapStruct community,

we love using MapStruct, but recently encountered a small issue. Consider the following Mapper:

@Mapper
public interface SomeMapper {

class SomeDto {

public String foo;
public String bar;
}

class SomeEntity {

public String foo;
public String bar;
}

@Mapping(target = "bar", expression = "java(magic(entity.bar))")
SomeDto toDto(SomeEntity entity);

default String magic(String input) {
return input.toUpperCase();
}
}

In the above code, the intent of the author was to apply some magic on the value of the "bar" field. Field "foo" has an implicit mapping added by MapStruct. The "problem" is that MapStruct resolves magic() as a mapping method and also applies it when mapping the "foo" field:

import javax.annotation.Generated;

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2019-10-25T12:38:35+0200",
    comments = "version: 1.3.0.Final, compiler: Eclipse JDT (IDE) 3.16.0.xx-201812291959-e2018-12-RELEASE, environment: Java 11.0.1 (Oracle Corporation)"
)
public class SomeMapperImpl implements SomeMapper {

    @Override
    public SomeDto toDto(SomeEntity entity) {
        if ( entity == null ) {
            return null;
        }

        SomeDto someDto = new SomeDto();

        someDto.foo = magic( entity.foo );

        someDto.bar = magic(entity.bar);

        return someDto;
    }
}

Of course this is very convenient in most of the situations, but brakes to above use-case. I know currently two workarounds, neither of them is elegant:

1.) put the helper method to an inner interface:

@Mapper
public interface SomeMapper {

class SomeDto {

public String foo;
public String bar;
}

class SomeEntity {

public String foo;
public String bar;
}

@Mapping(target = "bar", expression = "java(Helpers.magic(entity.bar))")
SomeDto toDto(SomeEntity entity);

interface Helpers {

static String magic(String input) {
return input.toUpperCase();
}
}
}


2.) annotate the method with @Named("..."):

@Mapper
public interface SomeMapper {

class SomeDto {

public String foo;
public String bar;
}

class SomeEntity {

public String foo;
public String bar;
}

@Mapping(target = "bar", expression = "java(magic(entity.bar))")
SomeDto toDto(SomeEntity entity);

@Named("workaround")
default String magic(String input) {
return input.toUpperCase();
}
}


Is there a more proper way to exclude a method from mapping method resolution?

I could imagine two approaches:

1.) Only consider methods for resolution which are annotated with a special annotation, for example "@MapperMethod". This would unfortunately break backwards compatibility, but would yield a cleaner API with less hidden magic.

2.) Provide an annotation for excluding methods from mapping method resolution like "@NonMapper" or "@Ignore"


What do you think?

Christian

unread,
Oct 29, 2019, 6:16:14 PM10/29/19
to mapstru...@googlegroups.com

Hi István,


this sounds more like a feature request than an issue. I think both of your solutions are okay, as you said not that elegant.. but ok.

And I totally understand your point that the "magic" could lead to unforeseen issues, but it also makes things less complicated. Maybe we could introduce something like a setting that disables this kind of implicit method resolution and requires some (new) explicit configuration. That's just one idea...


But feel free to raise a feature request on our GitHub (https://github.com/mapstruct/mapstruct/issues) so that our team can have a look and discuss.


Thanks a lot and best regards,

Christian

--
You received this message because you are subscribed to the Google Groups "mapstruct-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mapstruct-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/mapstruct-users/84b82221-8f84-4548-8c9f-d01669627be3%40googlegroups.com.

István Mészáros

unread,
Oct 31, 2019, 10:21:15 AM10/31/19
to mapstruct-users
Hi Christian,

thanks for your reply, I opened a feature proposal:



Best regards,
István
To unsubscribe from this group and stop receiving emails from it, send an email to mapstru...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages