为了账号安全,请及时绑定邮箱和手机立即绑定

具有连接实体属性的 Micronaut Data DTO 投影

具有连接实体属性的 Micronaut Data DTO 投影

人到中年有点甜 2023-09-06 16:55:47
我将 Micronaut Data 与 JPA 结合使用,并有两个实体。第一个是Recipe:@Entitypublic class Recipe {    @Id    @GeneratedValue(strategy = GenerationType.IDENTITY)    private Integer id;    private String name;    @ManyToOne    private Category category;    @OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)    private Set<Step> steps;// + other fields, getters and setters}第二个是ParseError指Recipe:@Entity@Table(name = "parse_error")public class ParseError implements Serializable {    @Id    @ManyToOne(fetch = FetchType.LAZY)    private Recipe recipe;    @Id    @Enumerated(EnumType.ORDINAL)    @Column(name = "problem_area")    private ProblemArea problemArea;    private String message;// + other fields, getters and setters}现在我想在 API 中提供带有ParseError属性的 DTO,但不提供整个Recipe实体,因为它包含在本例中不需要的 ManyToOne 和 OneToMany 关系。所以我为此创建了投影 DTO:@Introspectedpublic class ParseErrorDto {    private Integer recipeId;    private String recipeName;    private ParseError.ProblemArea problemArea;    private String message;// + getters and setters}并将listAll()方法添加到ParseErrorRepository:@Repositorypublic interface ParseErrorRepository extends CrudRepository<ParseError, Integer> {    List<ParseErrorDto> listAll();}但似乎 Micronaut Data 无法从嵌套实体投影属性,或者我错过了 DTO 或存储库方法中的某些内容:ParseErrorRepository.java:22:错误:无法实现存储库方法:ParseErrorRepository.listAll()。实体中不存在属性recipeId:ParseError我还尝试创建RecipeDto:@Introspectedpublic class RecipeDto {    private Integer id;    private String name;    // + getters and setters}并相应更新ParseErrorDto:@Introspectedpublic class ParseErrorDto {    private RecipeDto recipe;    private ParseError.ProblemArea problemArea;    private String message;    // + getters and setters}再次没有成功:ParseErrorRepository.java:22:错误:无法实现存储库方法:ParseErrorRepository.listAll()。[RecipeDto] 类型的属性 [recipe] 与实体中声明的等效属性不兼容:ParseErrorMicronaut Data 是否能够通过 DTO 投影来处理这个用例?如果没有,那么我如何在 Micronaut Data 中解决它?
查看完整描述

1 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

当前的解决方法是将实体 bean 映射到 Java 流或反应流中的 DTO bean,并手动或通过 Mapstruct 进行属性映射。


更新:这是评论中问题的答案,并举例说明了如何使用 Mapstruct 进行解决方法:

将 Mapstruct 依赖项添加到build.gradle中:

implementation "org.mapstruct:mapstruct:$mapstructVersion"

annotationProcessor "org.mapstruct:mapstruct-processor:$mapstructVersion"

testAnnotationProcessor "org.mapstruct:mapstruct-processor:$mapstructVersion"

定义映射器:


import org.mapstruct.Mapper;


@Mapper(

    componentModel = "jsr330"

)

public interface ParseErrorMapper {

    ParseErrorDto entityToDto(@NotNull ParseError parseError);


    EntityReference recipeToDto(@NotNull Recipe recipe);

}

这是控制器中该映射器的用法:


@Controller("/parse-error")

public class ParseErrorController {

    private final ParseErrorRepository repository;

    private final ParseErrorMapper mapper;


    public ParseErrorController(ParseErrorRepository repository, ParseErrorMapper mapper) {

        this.repository = repository;

        this.mapper = mapper;

    }


    @Get("all")

    @Transactional

    public Page<ParseErrorDto> getAll(final Pageable pageable) {

        return repository.findAll(pageable).map(mapper::entityToDto);

    }

}


查看完整回答
反对 回复 2023-09-06
  • 1 回答
  • 0 关注
  • 114 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信