Skip to content

Generic class with adder method and CollectionMappingStrategy.ADDER_PREFERRED fails #3310

@dsubelman

Description

@dsubelman

Expected behavior

When implementing a Mapper with collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED for a derived class that extends an abstract class, my expectation is that the Mapper implementation should utilize the add() method, if it is defined in the abstract class, instead of the set() method.

public abstract class AbstractClass<T>  {

    private List<T> items;

    public AbstractClass() {
    }

    public List<T> getItems() {
        return items;
    }

    public void setItems(List<T> items) {
        this.items = items;
    }

    public void addItem(T item) {
        if (items == null) {
            items = new ArrayList<>();
        }
        items.add(item);
    }

}
public class ConcreteClass extends AbstractClass<String> {

    public ConcreteClass() {
        super();
    }
	
}
public class ConcreteClassDto {

    private List<String> items;
	
    public ConcreteClassDto() {
		
    }

    public List<String> getItems() {
        return items;
    }

    public void setItems(List<String> items) {
       this.items = items;
    }
	
}
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED)
public interface ConcreteClassMapper {

    ConcreteClass toEntity(ConcreteClassDto dto);
	
}

I would expect the Mapper implementation to utilize the addItem() method instead of the set() method:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-06-16T19:45:38-0400",
    comments = "version: 1.5.5.Final, compiler: javac, environment: Java 17.0.4.1 (Oracle Corporation)"
)
public class ConcreteClassMapperImpl implements ConcreteClassMapper {

    @Override
    public ConcreteClass toEntity(ConcreteClassDto dto) {
        if ( dto == null ) {
            return null;
        }

        ConcreteClass concreteClass = new ConcreteClass();

        if ( dto.getItems() != null ) {
            for ( String item : dto.getItems() ) {
                concreteClass.addItem( item );
            }
        }

        return concreteClass;
    }
}

Actual behavior

The actual Mapper implementation utilizes the set()method:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2023-06-16T19:30:04-0400",
    comments = "version: 1.5.5.Final, compiler: javac, environment: Java 17.0.4.1 (Oracle Corporation)"
)
public class ConcreteClassMapperImpl implements ConcreteClassMapper {

    @Override
    public ConcreteClass toEntity(ConcreteClassDto dto) {
        if ( dto == null ) {
            return null;
        }

        ConcreteClass concreteClass = new ConcreteClass();

        List<String> list = dto.getItems();
        if ( list != null ) {
            concreteClass.setItems( new ArrayList<String>( list ) );
        }

        return concreteClass;
    }
}

Steps to reproduce the problem

Steps are described in the expected and actual behavior sections.

MapStruct Version

MapStruct 1.5.5.Final

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions