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'}}