禁止mapstruct在对象映射函数列表中使用单对象映射函数



我有两个微服务:我们称它们为A和b。

由B处理的实体,其中有对a实体的引用,被实现为一个简单的Long id(例如;groupId)

@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "WorkShifts")
@AllArgsConstructor
@Builder(toBuilder = true)
public class WorkShiftEntity extends BaseEntitySerial {
@Column(name = "group_id")
private Long groupId;
private String description;
@Column(name = "start_time")
private Time startTime;
@Column(name = "end_time")
private Time endTime;
@Column(name = "work_shift")
private Integer workShift;
}

我想要实现的是使用mapstruct填充B(由A持有)的缺失组数据。到目前为止,我尝试使用@AfterMapping函数从a请求丢失的数据。我的映射器是:

@Mapper(componentModel = "spring", uses = LocalTimeMapper.class, builder = @Builder(disableBuilder = true), config = CommonMapperConfig.class)
public abstract class WorkShiftMapper extends BaseMapper implements IBaseMapper<WorkShiftEntity, WorkShiftDTO, Long>, LogSupport {
@Autowired
RestTemplate restTemplate;
@Mapping(target = "groupId", source = "group.id")
public abstract WorkShiftEntity dtoToEntity(WorkShiftDTO workShiftDTO);
@AfterMapping
public void afterEntityToDto(final WorkShiftEntity workShiftEntity, @MappingTarget final WorkShiftDTO workShiftDTO) {
if (workShiftEntity == null) {
return;
}
GroupDTO groupDTO = EcofinderUtils.getGroupDTO(restTemplate, workShiftEntity.getGroupId());
try {
GenericUtils.enhanceDTOForAttributeWithDTO(workShiftDTO, groupDTO, "group");
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
getLogger().error(e.getMessage());
}
}
@AfterMapping
public void afterEntityToDtoList(final List<WorkShiftEntity> workShiftEntity, @MappingTarget final List<WorkShiftDTO> workShiftDTO) {
if (workShiftEntity == null || workShiftEntity.size() == 0) {
return;
}
List<GroupDTO> groups = EcofinderUtils.getAllGroupDTOById(restTemplate, workShiftEntity.stream().map(WorkShiftEntity::getGroupId).distinct().toList());
try {
//Compile the resulting DTOs with the data got from the registry
//Group
GenericUtils.enhanceDTOListWithDataFromDTOJoiningEntities(workShiftDTO, groups, workShiftEntity, "group", "groupId");
} catch (AppException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
getLogger().error(e.getMessage());
}
}
}

给出映射函数的实现接口是:

public interface IBaseMapper<T extends BaseEntity<K>, D extends IBaseDTO<K>, K extends Serializable> {
D entityToDto(T entity);
List<D> entityToDtoList(List<T> entity);
T dtoToEntity(D dto);
}

生成的代码的问题是,将实体列表映射到dto列表的函数对每个实体使用entityToDto,导致n个请求a。之后,调用另一个@AfterMapping函数(收集所有id并在一个请求中提取所有数据的函数,这是唯一一个应该在映射列表时使用的函数)。

//GENERATED CODE BY MAPSTRUCT
@Override
public WorkShiftDTO entityToDto(WorkShiftEntity workShiftEntity) {
if ( workShiftEntity == null ) {
return null;
}
WorkShiftDTO workShiftDTO = new WorkShiftDTO();
workShiftDTO.setId( workShiftEntity.getId() );
workShiftDTO.setDescription( workShiftEntity.getDescription() );
workShiftDTO.setStartTime( localTimeMapper.map( workShiftEntity.getStartTime() ) );
workShiftDTO.setEndTime( localTimeMapper.map( workShiftEntity.getEndTime() ) );
workShiftDTO.setWorkShift( workShiftEntity.getWorkShift() );
afterEntityToDto( workShiftEntity, workShiftDTO );
return workShiftDTO;
}
@Override
public List<WorkShiftDTO> entityToDtoList(List<WorkShiftEntity> entity) {
//more code...
List<WorkShiftDTO> list = new ArrayList<WorkShiftDTO>( entity.size() );
for ( WorkShiftEntity workShiftEntity : entity ) {
list.add( entityToDto( workShiftEntity ) );
}
afterEntityToDtoList( entity, list );
return list;
}

是否有一种方法可以使mapstruct实现entityToDto函数两次,其中一个版本使用@AfterMapping函数,而另一个版本不使用,以便使entityToDtoList函数使用没有@AfterMapping调用的版本?

类似:

@Override
public WorkShiftDTO entityToDto(WorkShiftEntity workShiftEntity) {
if ( workShiftEntity == null ) {
return null;
}
WorkShiftDTO workShiftDTO = new WorkShiftDTO();
workShiftDTO.setId( workShiftEntity.getId() );
workShiftDTO.setDescription( workShiftEntity.getDescription() );
workShiftDTO.setStartTime( localTimeMapper.map( workShiftEntity.getStartTime() ) );
workShiftDTO.setEndTime( localTimeMapper.map( workShiftEntity.getEndTime() ) );
workShiftDTO.setWorkShift( workShiftEntity.getWorkShift() );
afterEntityToDto( workShiftEntity, workShiftDTO );
return workShiftDTO;
}
public WorkShiftDTO entityToDtoNoAfter(WorkShiftEntity workShiftEntity) {
if ( workShiftEntity == null ) {
return null;
}
WorkShiftDTO workShiftDTO = new WorkShiftDTO();
workShiftDTO.setId( workShiftEntity.getId() );
workShiftDTO.setDescription( workShiftEntity.getDescription() );
workShiftDTO.setStartTime( localTimeMapper.map( workShiftEntity.getStartTime() ) );
workShiftDTO.setEndTime( localTimeMapper.map( workShiftEntity.getEndTime() ) );
workShiftDTO.setWorkShift( workShiftEntity.getWorkShift() );
return workShiftDTO;
}
@Override
public List<WorkShiftDTO> entityToDtoList(List<WorkShiftEntity> entity) {
//more code...
List<WorkShiftDTO> list = new ArrayList<WorkShiftDTO>( entity.size() );
for ( WorkShiftEntity workShiftEntity : entity ) {
list.add( entityToDtoNoAfter( workShiftEntity ) );
}
afterEntityToDtoList( entity, list );
return list;
}

其他方法都是受欢迎的,这种方法对我来说更自然。

提前感谢!

经过两天的深入研究和多次尝试,我想我已经找到了一个不错的解决方案。

我可以给函数一个名字,这样它们就像有一个特定的作用域一样工作。映射器接口变为:

public interface IBaseMapper<T extends BaseEntity<K>, D extends IBaseDTO<K>, K extends Serializable> {
@BeanMapping(qualifiedByName = "EntityToDTO")
D entityToDto(T entity);
@Named("EntityToDTOList")
public abstract D entityToDTOListEntity(T entity);
@IterableMapping(qualifiedByName = "EntityToDTOList")
List<D> entityToDtoList(List<T> entity);
T dtoToEntity(D dto);
}

这样我就可以把我需要的所有功能组合在一起。

映射器抽象类:

@Mapping(target = "groupId", source = "group.id")
public abstract WorkShiftEntity dtoToEntity(WorkShiftDTO workShiftDTO);
@AfterMapping
@Named("EntityToDTO")
public void afterEntityToDto(final WorkShiftEntity workShiftEntity, @MappingTarget final WorkShiftDTO workShiftDTO) {
if (workShiftEntity == null) {
return;
}
GroupDTO groupDTO = EcofinderUtils.getGroupDTO(restTemplate, workShiftEntity.getGroupId());
try {
GenericUtils.enhanceDTOForAttributeWithDTO(workShiftDTO, groupDTO, "group");
} catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
getLogger().error(e.getMessage());
}
}
@AfterMapping
@Named("EntityToDTOList")
public void afterEntityToDtoList(final List<WorkShiftEntity> workShiftEntity, @MappingTarget final List<WorkShiftDTO> workShiftDTO) {
if (workShiftEntity == null || workShiftEntity.size() == 0) {
return;
}
List<GroupDTO> groups = EcofinderUtils.getAllGroupDTOById(restTemplate, workShiftEntity.stream().map(WorkShiftEntity::getGroupId).distinct().toList());
try {
//Compile the resulting DTOs with the data got from the registry
//Group
GenericUtils.enhanceDTOListWithDataFromDTOJoiningEntities(workShiftDTO, groups, workShiftEntity, "group", "groupId");
} catch (AppException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) {
getLogger().error(e.getMessage());
}
}
这样,生成的Impl类是:
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2022-05-20T15:08:38+0200",
comments = "version: 1.4.2.Final, compiler: javac, environment: Java 17.0.1 (Oracle Corporation)"
)
@Component
public class WorkShiftMapperImpl extends WorkShiftMapper {
@Autowired
private LocalTimeMapper localTimeMapper;
@Override
public WorkShiftDTO entityToDto(WorkShiftEntity entity) {
if ( entity == null ) {
return null;
}
WorkShiftDTO workShiftDTO = new WorkShiftDTO();
workShiftDTO.setId( entity.getId() );
workShiftDTO.setDescription( entity.getDescription() );
workShiftDTO.setStartTime( localTimeMapper.map( entity.getStartTime() ) );
workShiftDTO.setEndTime( localTimeMapper.map( entity.getEndTime() ) );
workShiftDTO.setWorkShift( entity.getWorkShift() );
afterEntityToDto( entity, workShiftDTO );
return workShiftDTO;
}
@Override
public WorkShiftDTO entityToDTOListEntity(WorkShiftEntity entity) {
if ( entity == null ) {
return null;
}
WorkShiftDTO workShiftDTO = new WorkShiftDTO();
workShiftDTO.setId( entity.getId() );
workShiftDTO.setDescription( entity.getDescription() );
workShiftDTO.setStartTime( localTimeMapper.map( entity.getStartTime() ) );
workShiftDTO.setEndTime( localTimeMapper.map( entity.getEndTime() ) );
workShiftDTO.setWorkShift( entity.getWorkShift() );
return workShiftDTO;
}
@Override
public List<WorkShiftDTO> entityToDtoList(List<WorkShiftEntity> entity) {
if ( entity == null ) {
return null;
}
List<WorkShiftDTO> list = new ArrayList<WorkShiftDTO>( entity.size() );
for ( WorkShiftEntity workShiftEntity : entity ) {
list.add( entityToDTOListEntity( workShiftEntity ) );
}
afterEntityToDtoList( entity, list );
return list;
}
@Override
public WorkShiftEntity dtoToEntity(WorkShiftDTO workShiftDTO) {
if ( workShiftDTO == null ) {
return null;
}
WorkShiftEntity workShiftEntity = new WorkShiftEntity();
workShiftEntity.setGroupId( workShiftDTOGroupId( workShiftDTO ) );
workShiftEntity.setId( workShiftDTO.getId() );
workShiftEntity.setDescription( workShiftDTO.getDescription() );
workShiftEntity.setStartTime( localTimeMapper.map( workShiftDTO.getStartTime() ) );
workShiftEntity.setEndTime( localTimeMapper.map( workShiftDTO.getEndTime() ) );
workShiftEntity.setWorkShift( workShiftDTO.getWorkShift() );
return workShiftEntity;
}
private Long workShiftDTOGroupId(WorkShiftDTO workShiftDTO) {
if ( workShiftDTO == null ) {
return null;
}
GroupDTO group = workShiftDTO.getGroup();
if ( group == null ) {
return null;
}
Long id = group.getId();
if ( id == null ) {
return null;
}
return id;
}
}

这正是我想要的

最新更新