Calling mapper interface method from another mapper interface code

In this post under MapStruct, I will show with example how to call one mapper interface method from another mapper interface code.

For our example I will create “Address” pojo class that will be shared by “Student” and “Person” pojo class as shown below.

Address

package package31;

public class Address {
    private String addressLine1;
    private String addressLine2;

    //Removed getter and setter for brevity
}

Person

package package31;

public class Person {
    private int id;
    private String name;
    private Address address;

    //Removed getter and setter for brevity
}

Student

package package31;

public class Student {
    private int id;
    private String name;
    private Address address;

    //Removed getter and setter for brevity
}

As you can see both “Person” and “Student” refer to “Address” pojo class.

For these pojo classes we will have corresponding dto classes named “PersonDTO”, “StudentDTO”, and “AddressDTO” as shown below

AddressDTO

package package31;

public class AddressDTO {
    private String streetLine1;
    private String streetLine2;

    //Removed getter and setter for brevity
}

PersonDTO

package package31;

public class PersonDTO {
    private int id;
    private String name;
    private AddressDTO addressDTO;

    //Removed getter and setter for brevity
}

StudentDTO

package package31;

public class StudentDTO {
    private int id;
    private String name;
    private AddressDTO addressDTO;

    //Removed getter and setter for brevity
}

Now lets create the mapper interface for all three pojo class.

AddressMapper

package package31;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper
public interface AddressMapper {
    @Mapping(target = "streetLine1", source = "addressLine1")
    @Mapping(target = "streetLine2", source = "addressLine2")
    AddressDTO getDTOFromModel(Address address);
}

PersonMapper

package package31;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(uses = AddressMapper.class)
public interface PersonMapper {
    @Mapping(target = "addressDTO", source = "address")
    PersonDTO getDTOFromModel(Person person);
}

In the above code, as usual I am annotating “PersonMapper” interface with “@Mapper” annotation marking it as a mapper interface and I am also setting “uses” attribute to another mapper interface which
is “AddressMapper” interface.

In this way, we are telling MapStruct framework that when mapping “Person” instance to “PersonDTO” instance, if you encounter property of type “Address” use “AddressMapper” interface to map it to “AddressDTO”
instance.

The actual implementation class generated by MapStruct is as shown below

PersonMapperImpl

package package31;

import org.mapstruct.factory.Mappers;

/*
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-10-02T11:39:16+0530",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.5.jar, environment: Java 21.0.4 (Amazon.com Inc.)"
)
*/
public class PersonMapperImpl implements PersonMapper {

    private final AddressMapper addressMapper = Mappers.getMapper( AddressMapper.class );

    @Override
    public PersonDTO getDTOFromModel(Person person) {
        if ( person == null ) {
            return null;
        }

        PersonDTO personDTO = new PersonDTO();

        personDTO.setAddressDTO( addressMapper.getDTOFromModel( person.getAddress() ) );
        personDTO.setId( person.getId() );
        personDTO.setName( person.getName() );

        return personDTO;
    }
}

As you can see in the above code, at line 24, to map “Address” instance to “AddressDTO”, MapStruct is using “AddressMapper” interface.

Same change we will do for “StudentMapper” interface as shown below

StudentMapper

package package31;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(uses = AddressMapper.class)
public interface StudentMapper {
    @Mapping(target = "addressDTO", source = "address")
    StudentDTO getDTOFromModel(Student student);
}

The actual implementation class generated by MapStruct is as shown below

StudentMapperImpl

package package31;

import org.mapstruct.factory.Mappers;

/*
@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2025-10-02T11:38:54+0530",
    comments = "version: 1.5.5.Final, compiler: IncrementalProcessingEnvironment from gradle-language-java-8.5.jar, environment: Java 21.0.4 (Amazon.com Inc.)"
)
*/
public class StudentMapperImpl implements StudentMapper {

    private final AddressMapper addressMapper = Mappers.getMapper( AddressMapper.class );

    @Override
    public StudentDTO getDTOFromModel(Student student) {
        if ( student == null ) {
            return null;
        }

        StudentDTO studentDTO = new StudentDTO();

        studentDTO.setAddressDTO( addressMapper.getDTOFromModel( student.getAddress() ) );
        studentDTO.setId( student.getId() );
        studentDTO.setName( student.getName() );

        return studentDTO;
    }
}

As you can see in the above code, at line 24, to map “Address” instance to “AddressDTO”, MapStruct is using “AddressMapper” interface.

In this way we can call one mapper interface method from another mapper interface code.

Below is the main class for your reference

Main class

package package31;

import org.mapstruct.factory.Mappers;

public class Example31 {
    public static void main(String[] args) {
        StudentMapper studentMapper = Mappers.getMapper(StudentMapper.class);
        PersonMapper personMapper = Mappers.getMapper(PersonMapper.class);

        Address studentAddress = new Address();
        studentAddress.setAddressLine1("student address line 1");
        studentAddress.setAddressLine2("student address line 2");

        Student student = new Student();
        student.setId(1);
        student.setName("John");
        student.setAddress(studentAddress);

        Address personAddress = new Address();
        personAddress.setAddressLine1("person address line 1");
        personAddress.setAddressLine2("person address line 2");

        Person person = new Person();
        person.setId(1);
        person.setName("Troy");
        person.setAddress(personAddress);

        PersonDTO personDTO = personMapper.getDTOFromModel(person);
        System.out.println(personDTO);

        StudentDTO studentDTO = studentMapper.getDTOFromModel(student);
        System.out.println(studentDTO);
    }
}

Below is the output

Output

PersonDTO{id=1, name='Troy', addressDTO=AddressDTO{streetLine1='person address line 1', streetLine2='person address line 2'}}
StudentDTO{id=1, name='John', addressDTO=AddressDTO{streetLine1='student address line 1', streetLine2='student address line 2'}}

Leave a comment