Mapstruct-如何将DTO字符串参数转换为实体对象



我是Mapstruct的新手,我正在努力正确理解它。

我想要实现的是从DTO字符串参数(carModel)转换为他的实体,使用服务和存储库进行检索。

问题是Mapstruct生成的Mapper类试图用@Autowired注释注入Service类,但它不起作用。服务为null。

这是我的@Mapper类:

@Mapper(componentModel = "spring", uses = CarModelService.class)
public interface KitMapper extends EntityMapper<KitDTO, Kit> {
KitMapper INSTANCE = Mappers.getMapper(KitMapper.class);
@Mapping(source = "weight", target = "systemWeight")
@Mapping(source = "carModel", target = "carModel")
Kit toEntity(KitDTO kitDTO);
}
public interface EntityMapper<D, E> {
E toEntity(D dto);
List<E> toEntity(List<D> dtoList);
}

@Service类:

@Service
@Transactional
public class CarModelService {
private final CarModelRepository carModelRepository;
@Transactional(readOnly = true)
public CarModel findByName(String name) {
return carModelRepository.findByName(name).orElse(null);
}
}

@Repository类:

@Repository
public interface CarModelRepository extends JpaRepository<CarModel, Long> {
Optional<CarModel> findByName(String carModelName);
}

DTO和实体类:

public class KitDTO {
private String id;
private String carModel; // e.g. "Ferrari Monza"
....
}
@Entity
@Table(name = "kit")
public class Kit implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "id")
private Long id;
@ManyToOne
private CarModel carModel;
...
}
@Entity
@Table(name = "car_model")
public class CarModel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
@SequenceGenerator(name = "sequenceGenerator")
@Column(name = "id")
private Long id;
@Column(name = "name")
private String name;
...
}

构建工作正常,但当我尝试使用Mapper时,应用程序会停止。它说carModelService为空。以下是映射程序生成的实现类:

@Component
public class KitMapperImpl implements KitMapper {
@Autowired // <-- this seems not working
private CarModelService carModelService;
@Override
public Kit toEntity(KitDTO kitDTO) {
if ( kitDTO == null ) {
return null;
}
Kit kit = new Kit();
kit.setSystemWeight( String.valueOf( kitDTO.getWeight() ) );
kit.carModel( carModelService.findByName(kitDTO.getCarModel()) ); // <-- carModelService is null!
// other setters
return kit;
}
}

我已经尝试了很多方法,使用Decorator、@Context、expression,将@Mapper类注入@Service类。

我发现了很多问题,但实际上没有人帮我:

Mapstruct-如何在Generated Mapper类中注入spring依赖项

@服务类未在org.mapstruct.@Mapper Class 中自动连接

调试时,MapStruct映射器未使用autowired进行初始化

任何帮助都将不胜感激!提前感谢!

找到了解决方案!

我没有从@RestController类直接调用Mapper方法toEntity(),而是在CarModelService类中注入了Mapper,并创建了一个调用Mapper的方法。通过这种方式,流程是:

控制器-->服务-->映射器

@Service
@Transactional
public class KitService {
private final KitRepository kitRepository;
private final KitSearchRepository kitSearchRepository;
private final KitMapper kitMapper; // <-- mapper declaration
public KitService(KitRepository kitRepository, KitSearchRepository kitSearchRepository, KitMapper kitMapper) {
this.kitRepository = kitRepository;
this.kitSearchRepository = kitSearchRepository;
this.kitMapper = kitMapper; // <-- mapper initilization
}
// here the method which calls mapper
public Kit convertDTOToEntity(KitDTO kitDTO) {
return kitMapper.toEntity(kitDTO);
}

通过这种方式,Mapstruct生成的类不会在CarModelService上产生错误。

看来这种方法是实现这一点的唯一途径,创造一个"王者";"桥";在服务和映射器之间。

(您也可以使用@Autowired注释而不是构造函数)

您能分享错误消息吗?从您共享的信息中,我可以看到KitDto中的carModel是String,Entity中的carModel是carModel类。不确定mapstruct的自动生成的实现类是如何实现的:kit.carModel( carModelService.findByName(kitDTO.getCarModel()) );

但我想分享另一种方法,不知道这是否是最佳实践。在这种方法中,您可以创建一个abstract类的mapper,在其中您可以@Autowired repository手动添加这些映射。我分享了它的片段。希望这能对你有所帮助。

@Mapper(componentModel = "spring", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
public abstract class ProductMapper {
@Autowired 
private CarModelService carModelService;

public abstract Kit convertDTOToEntity(KitDTO kitDTO);

public Kit toEntity(KitDTO kitDTO);
{   
Kit kit = convertDTOToEntity(kitDTO);
kit.setCarModel(carModelService.findByName(kitDTO.getCarModel()));
return kit;
}
}

对其他方法感到好奇,将遵循此线索。我们可以讨论的最佳实践

相关内容

  • 没有找到相关文章

最新更新