簡體   English   中英

具有來自連接實體的屬性的 Micronaut 數據 DTO 投影

[英]Micronaut Data DTO projection with properties from joined entities

我將 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 中解決它?

現在(在最新版本 1.0.0.M1 中)這是不可能的。 所以我為此創建了功能請求問題:https://github.com/micronaut-projects/micronaut-data/issues/184

Current workaround is to map entity bean into DTO bean in Java stream or reactive stream for example and do the properties mapping manually or by 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 中該映射器的用法:

@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);
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM