rest MapStruct Java流
您好,我对streams等非常陌生,只是出于培训目的,我正在尝试使用mapstruct构建简单的api。 我的问题是,我真的不知道如何返回转换后的父值以及该实体中的转换字段
这是我的简单目标
public class RecipeDTO {
private Integer id;
private String title;
private String description;
private String imgUrl;
private String directions;
private String prepTime;
private Integer servings;
private String category;
private Set<IngredientDTO> ingredientDTOSet = new HashSet<>();
}
实体
public class Recipe {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "recipe_id")
private Integer id;
@NotNull
@Column(name = "recipe_title")
private String title;
@NotNull
@Column(name = "recipe_description")
private String description;
@Column(name = "recipe_img_url")
private String imgUrl;
@NotNull
@Column(name = "recipe_direction")
private String directions;
@NotNull
@Column(name = "prep_time")
private String prepTime;
@NotNull
@Column(name = "servings")
private Integer servings;
@NotNull
@Column(name = "category")
private String category;
@OneToMany(mappedBy = "recipe",
cascade = CascadeType.ALL)
private Set<Ingredient> ingredients = new HashSet<>();
}
服务(仅一种方法)
@Override
public List<RecipeDTO> findAll() {
log.debug("\n" + this.getClass().getSimpleName() + " -> findAll() \n");
return recipeRepository.findAll()
.stream()
.map(recipe -> RecipeMapper.INSTANCE.recipeToRecipeDTO(recipe))
.collect(Collectors.toList());
}
@Mapper(componentModel = "spring", uses = {IngredientMapper.class})
public interface RecipeMapper {
RecipeMapper INSTANCE = Mappers.getMapper(RecipeMapper.class);
@Mappings({
@Mapping(source = "ingredients", target = "ingredientDTOSet")
})
RecipeDTO recipeToRecipeDTO(Recipe recipe);
}
如何转换嵌套bean? 当我试图获取所有食谱时,抛出异常
爪哇。lang.NullPointerException:null 在com。马特乌斯兹格博斯基。爸爸。应用程序编程接口。制图员。RecipeMapperImpl。ingredientSetToIngredientDTOSet(RecipeMapperImpl.java:52)~[classes/:na] 在com。马特乌斯兹格博斯基。爸爸。应用程序编程接口。制图员。RecipeMapperImpl。recipeToRecipeDTO(RecipeMapperImpl.java:32)~[classes/:na] 在com。马特乌斯兹格博斯基。爸爸。服务RecipeServiceImpl。lambda$findAll$0(RecipeServiceImpl.java:38)~[classes/:na] 在爪哇。util。流动参考管道$3$1。接受(ReferencePipeline.java:193)~[na:1.8.0\u 181] 在爪哇。util。ArrayList$ArrayListSpliterator。foreachreserving(ArrayList.java:1382)~[na:1.8.0_181] 在爪哇。util。流动抽象管道。copyInto(AbstractPipeline.java:481)~[na:1.8.0_181] 等等
看起来是有配料的,但当我在做食谱时,并不是所有的东西都是好的
# 1 楼答案
这不是关于java流的问题。Java流api正在调用
recipeToRecipeDTO
方法,该方法失败。理想情况下,方法recipeToRecipeDTO
应该能够将整个配方对象转换为RecipeDTO要解决此问题,需要在
RecipeMapper
中添加一个方法,将一个Ingredient
实体对象转换为IngredientDTO
# 2 楼答案
您可以使用流的映射功能
我假设您的mapstruct方法名为“convert”,映射器的变量名为“mapper”
列表的映射将为流中的每个条目调用给定的方法(mapper::convert),然后流将包含该方法所有调用的所有返回值。因此,在您的情况下:它将转换列表中的每个条目,然后列表将包含所有转换的元素
之后,您只需要再次收集流,这样您就又有了一个列表
编辑后,此答案不再有效,因为您已更改了问题并使用了我的答案
关于你的后续问题: 一般来说,要转换嵌套bean:只要嵌套bean的结构相同,mapstruct就会立即进行转换。如果存在差异,则必须对其进行注释。如果没有看到代码的这一部分,我无法告诉您Ingrediant和IngRediantTo之间的区别
您可以尝试查看生成的类,并查看导致NullPointerException的行。那么你有胶水有什么区别。然后将其注释到mapper界面
一般来说,对于嵌套bean: 1) 您可以在映射器中添加接口方法“ingredientToIngredientDTO”。并在该方法的右侧注释差异(如果需要)。MapStruct将它用于RecipeToripedTo方法! 2) 您可以注释嵌套的差异。例如@Mapping(source=“components.nameA”,target=“ingrediendtoset.nameB”)
但你现在提出的问题与开始时完全不同,要回答这个问题,我需要更多的信息。因此,我更愿意将其重新编辑为原始问题。如果我的提示还不够,可以问一个有足够信息的新的
# 3 楼答案
问题是您将
componentModel = "spring"
与Mappers
工厂混合在一起。当您使用spring组件模型时,所使用的映射器将自动连接到生成的类中,Mappers
工厂仅初始化实例。这意味着您的配方映射器没有被注入为了解决这个问题,您应该在任何地方使用默认的componentModel,或者使用spring并注入映射器
另外,您现在进行映射的方式并不是真正的性能。您只需向映射器添加一个映射列表的方法,并调用该方法,而不用使用流