MapStruct: Mapping 2 objects to a 3rd one

anij picture anij · Dec 7, 2015 · Viewed 13.2k times · Source

I have Object1 and Object2. Now, I want to map object3, with attributes from 1 & 2.

Say, I have 2 object:

1. User: {first_name, last_name, id}
2. Address: {street, locality, city, state, pin, id}

Now, with these, I want to map that in

User_View: {firstName, lastName, city, state}.

Where, first_name & last_name will be from User object and city & state from Address object.

Now, my question is, how to do that?

However, currently, I'm doing like this

@Mapper    
public abstract class UserViewMapper {
        @Mappings({
                    @Mapping(source = "first_name", target = "firstName"),
                    @Mapping(source = "last_name", target = "lastName"),
                    @Mapping(target = "city", ignore = true),
                    @Mapping(target = "state", ignore = true)

            })
            public abstract UserView userToView(User user);

        public UserView addressToView(UserView userView, Address address) {

                if (userView == null) {
                    return null;
                }

                if (address == null) {
                    return null;
                }

                userView.setCity(address.getCity());
                userView.setState(address.getState()); 

            return userView;

            }
    }

But, here, I have to manually write the mapping in addressToView().

Therefore, is there, any way, to avoid that?

Or, what would be the preferred way, to handle such situations?

Answer

Gunnar picture Gunnar · Dec 7, 2015

You can declare a mapping method with several source parameters and refer to the properties of all these parameters in your @Mapping annotations:

@Mapper
public abstract class UserViewMapper {

    @Mapping(source = "first_name", target = "user.firstName"),
    @Mapping(source = "last_name", target = "user.lastName"),
    public abstract UserView userAndAddressToView(User user, Address address);
}

As the "city" and "state" property names match in source and target, there is no need for mapping them.

Also see the chapter "Defining a mapper" in the reference documentation for more details.