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
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);
}
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With