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

我将 Micronaut Data 与 JPA 结合使用,并有两个实体。第一个是Recipe:


@Entity

public 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:


@Introspected

public class ParseErrorDto {

    private Integer recipeId;


    private String recipeName;


    private ParseError.ProblemArea problemArea;


    private String message;


// + getters and setters

}

并将listAll()方法添加到ParseErrorRepository:


@Repository

public interface ParseErrorRepository extends CrudRepository<ParseError, Integer> {

    List<ParseErrorDto> listAll();

}

但似乎 Micronaut Data 无法从嵌套实体投影属性,或者我错过了 DTO 或存储库方法中的某些内容:


ParseErrorRepository.java:22:错误:无法实现存储库方法:ParseErrorRepository.listAll()。实体中不存在属性recipeId:ParseError


我还尝试创建RecipeDto:


@Introspected

public class RecipeDto {

    private Integer id;


    private String name;


    // + getters and setters

}

并相应更新ParseErrorDto:


@Introspected

public class ParseErrorDto {

    private RecipeDto recipe;


    private ParseError.ProblemArea problemArea;


    private String message;


    // + getters and setters

}

再次没有成功:


ParseErrorRepository.java:22:错误:无法实现存储库方法:ParseErrorRepository.listAll()。[RecipeDto] 类型的属性 [recipe] 与实体中声明的等效属性不兼容:ParseError


Micronaut Data 是否能够通过 DTO 投影来处理这个用例?如果没有,那么我如何在 Micronaut Data 中解决它?


人到中年有点甜
浏览 115回答 1
1回答

隔江千里

当前的解决方法是将实体 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);    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java