Reputation: 2023
i have an object school that has an object person, persons are already saved in a data base and when i save a school object i give it a person id
so in the class school i have an attribute person of type Person, and in SchoolDTO i have an attribute personId of type Long
@Mapper(componentModel = "spring", uses = { PersonMapper.class })
public interface SchoolMapper extends EntityMapper<SchoolDTO, School>{
@Mapping(source = "personId", target = "person")
School toEntity(SchoolDTO schoolDTO);
}
School school = schoolMapper.toEntity(schoolDTO);
log.info(school.getPerson());
public interface EntityMapper <D, E> {
E toEntity(D dto);
D toDto(E entity);
List <E> toEntity(List<D> dtoList);
List <D> toDto(List<E> entityList);
}
@Mapper(componentModel = "spring", uses = {})
public interface PersonMapper extends EntityMapper<PersonDTO, Person> {
default Person fromId(Long id) {
if (id == null) {
return null;
}
Person person= new Person();
person.setId(id);
return person;
}
}
the problem here when i display the person it shows me the id with their value and the other attribute null
Upvotes: 15
Views: 23551
Reputation: 2026
We can generalize the previous answer by introducing a ReferenceMapper, like this:
@Component
public class ReferenceMapper {
@PersistenceContext
private EntityManager entityManager;
@ObjectFactory
public <T> T map(@NonNull final Long id, @TargetType Class<T> type) {
return entityManager.getReference(type, id);
}
}
Then, PersonMapper would be:
@Mapper(componentModel = "spring", uses = {ReferenceMapper.class})
public interface PersonMapper {
Person toEntity(Long id);
}
And finally SchoolMapper:
@Mapper(componentModel = "spring",uses = {PersonMapper.class})
public interface SchoolMapper {
@Mapping(source = "personId", target = "person")
School toEntity(SchoolDTO schoolDTO);
}
And generated source would be:
@Override
public School toEntity(InDto dto) {
if ( dto == null ) {
return null;
}
School school = new School();
school.setPerson( personMapper.toEntity( dto.getPersonId() ) );
// other setters
return school;
}
Upvotes: 10
Reputation: 21471
The reason why your Person
is displayed only with the id value set is because your fromId
method creates an empty Person
and sets only the id.
I presume you want to fetch the Person
from the database.
To achieve this you just need to tell MapStruct to use a service, or you can inject it in your mapper and perform the fetch.
If you have a service like:
public interface PersonService {
Person findById(Long id);
}
And your mapper:
@Mapper(componentModel = "spring", uses = { PersonService.class })
public interface SchoolMapper extends EntityMapper<SchoolDTO, School>{
@Mapping(source = "personId", target = "person")
School toEntity(SchoolDTO schoolDTO);
}
Upvotes: 25