简体   繁体   中英

Mapstruct map one field to multiple target fields and vice versa

I've referred the question Map multiple source fields to same type target fields with Mapstruct but it doesn't help

My rest resource classes are like below

class Base {
//fields
//getters and setters
}

Class A extends Base{
List<String> emailAdddress;
//other fields
//getters and setters
}

Class B extends Base{
List<String> devices;
//other fields
//getters and setters
}

Class C extends Base{
List<String> mobileNumbers;
//other fields
//getters and setters
}

My entity class is Source, like below:

 Class Source {
    String address
    //other fields
    //getters and setters
    }

I want to map the address from Source class with emailAdddress or devices or mobileNumbers in my mapper class, I tried using @AfterMapping in the mapper class and also a decorator class but it didnt help.

I've a mapper class like this

@Mapper
public abstract class AddressMapper {
     //basic mappings here

public abstract Source toEntity(Base b);
public abstract Base toDomain(Source src);

   @AfterMapping 
   public void setAddressInfo(@MappingTarget Source src, B b) {
        src.setAddress(b.getDevices().toString());
}

I am not sure that I quite follow what you are trying to do.

However, if you want to map the specific classes ( A , B , C you would need to put those in the methods. As MapStruct is an annotation processor and during compilation time it only knows about the Base fields in your example. What you can do is something like the following:

@Maper
public interface AdressMapper {


    default Source toEntity(Base b) {
        if (b == null) {
            return null;
        } else if (b instanceOf A) {
            toEntity((A) b);
        } else if (b instanceOf B) {
            toEntity((A) b);
        } else if (b instanceOf C) {
            toEntity((C) b);
        } else {
            // Decide what to do
        }
    }

    @Mapping(target = "address", source = "emailAddress")
    Source toEntity(A a);

    @Mapping(target = "address", source = "devices")
    Source toEntity(B b);

    @Mapping(target = "address", source = "mobileNumbers")
    Source toEntity(C c);

    default Base toDomain(Source source) {
        if (source == null) {
            return null;
        } else if (condition to match to A) {
            return toDomainA(source);
        } else if (condition to match to B) {
            return toDomainB(source);
        } else if (condition to match to C) {
            return toDomainC(source);
        }
    }

    @Mapping(target = "emailAddress", source = "address")
    A toDomainA(Source source);

    @Mapping(target = "devices", source = "address")
    B toDomainB(Source source);

    @Mapping(target = "mobileNumbers", source = "address")
    C toDomainB(Source source);


    // This method is needed so MapStruct knows how to map from List<String> into String
    static <T> String listToString(List<T> list) {
        if (list == null) {
            return null;
        }

        return list.toString();
    }

    // This method is needed so MapStruct know hot to map from String into List<String>
    static List<String> fromListToString(String string) {
        if (string == null) {
            return null;
        }

        // Perform your own conversion
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM