简体   繁体   中英

MapStruct Retrieving from arrayList

I'm trying to use MapStruct to map two objects. I have been searching for a while and I haven't been able to find anything, though I'm new to programming so I'm sure it's easier than I'm making it.

Here is some stripped back code (Note that the real code is more complex, with the child object from the arraylist not being the same type as the destination objects child variable as it is here):

SourceObject

public class SourceObject {
    public ArrayList<ListObject> list = new ArrayList<ListObject>();

    public SourceObject() {
        list.add(new ListObject());
    }
}

ListObject

public class ListObject {
    public DetailsObject details = new DetailsObject();

    public ListObject() {
        details.forename="SourceForename";
        details.surname="SourceSurname";
    }
}

DestinationObject

public class DestinationObject {
    public DetailsObject details = new DetailsObject();

    public DestinationObject() {
        details.forename="DestinationForename";
        details.surname="DestinationSurname";
    }
}

DetailsObject

public class DetailsObject {
    public String forename;
    public String surname;
}

Mapper

@Mappings({
    @Mapping(target="details.forename", source="list.get(0).details.forename"),
    @Mapping(target="details.surname", source="list.get(0).details.surname"),
})
DestinationObject toDestination(SourceObject source);

This will work fine if I put DetailsObject directly inside SourceObject, but becomes a problem when I try to take it from the list. The error I get is:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.5.1:compile (default-compile) on project template: Compilation failure: Compilation failure:

[ERROR] .../src/main/java/Mapper/SourceToDestinationMap.java:[12,13] No property named "list.get(0).details.surname" exists in source parameter(s). Did you mean "list.empty"?

[ERROR] .../src/main/java/Mapper/SourceToDestinationMap.java:[11,9] No property named "list.get(0).details.forename" exists in source parameter(s). Did you mean "list.empty"?

EDIT: Current state of the mapper:

@Mapper
public interface SourceToDestinationMap {

    @Mapping(target = "details", source = "list")
    DestinationObject toDestination(SourceObject source);

    default DetailsObject map(List<ListObject> source) {
        return map(source.get(0));
    }

    DetailsObject map(ListObject source);
}

The mapping you are trying to do is not possible, since you are mixing bean properties and bean functions.

You can't use @Mapping(source = "list.get(0).XXX") . Using indexes to access elements of a list is not yet supported see #1321 .

A way to solve your problem would be to use Qualifiers in the same way that they are used in the mapstruct-iterable-to-non-iterable example.

Or you can provide your own method that would perform the mapping.

@Mapper
public interface MyMapper {

    @Mapping(target = "details", source = "list")
    DestinationObject toDestination(SourceObject source);

    default DetailsObject map(List<ListObject> source) {
        return source != null && !source.isEmpty() ? map(source.get(0)) : null;
    }

    DetailsObject map(ListObject source);
}

MapStruct will then generate the correct code.

Another alternative would be to use @Mapping(expression="java()" .

Your mapper will then look like:

@Mapper
public interface MyMapper {

    @Mapping(target = "details.forename", expression = "java(source.list.get(0).details.forename)")
    @Mapping(target = "details.surname", expression = "java(source.list.get(0).details.surname)")
    DestinationObject toDestination(SourceObject source);
}

Note for expression . MapStruct will use the text from the expression as is, and won't perform any validation checks. Therefore it can be a bit brittle, as there won't be null and empty checks.

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