当前位置: 首页 > 知识库问答 >
问题:

具有关联实体属性的Micronaut数据DTO投影

裴劲
2023-03-14

我在JPA中使用Micronaut数据,并且有两个实体。第一个是< code >配方:

@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中为DTO提供ParseError属性,但不提供整个配方实体,因为它包含MonyToOne和OneToMany关系,在这种情况下不需要。因此,我为此创建了投影 DTO:

@Introspected
public class ParseErrorDto {
    private Integer recipeId;

    private String recipeName;

    private ParseError.ProblemArea problemArea;

    private String message;

// + getters and setters
}

并将< code>listAll()方法添加到< code > parse error repository 中:

@Repository
public interface ParseErrorRepository extends CrudRepository<ParseError, Integer> {
    List<ParseErrorDto> listAll();
}

但似乎Micronaut Data无法从嵌套实体中投射属性,或者我在DTO或存储库方法中遗漏了一些东西:

ParseErrorRepository.java:22:错误:无法实现存储库方法:ParseErrorRepository.listAll()。实体中不存在属性累赘ID: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: error: 無法實現 Repository 方法: ParseErrorRepository.listAll().类型为 [RecipeDto] 的属性 [recipe] 与实体中声明的等效属性不兼容:ParseError

Micronaut Data 是否能够通过 DTO 投影来处理此用例?如果没有,那么有没有另一种方法可以在Micronaut Data中解决它?

共有1个答案

鲜于岳
2023-03-14

现在(在最新版本1.0.0.M1中)这是不可能的。因此,我为此创建了功能请求问题:https://github.com/micronaut-projects/micronaut-data/issues/184

当前的解决方法是将实体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);
    }
}
 类似资料:
  • 早上好 我正在使用ModelMapper将DTO映射到实体,反之亦然,与此相关,我有一个问题。 1)当我从SonController获取SonDTO时,我需要将长的motherId映射到实体Son,但在那里我有实体mothermother来建立关系,它在内部有id。那么我如何将这个SonDTO motherId映射到实体mothermother中,反之亦然? 类以下:

  • 关联实体和关联关系属性有什么区别?在我的一本名为《现代数据库管理》(Hoffer,第11版)的书中,作者陈述了两者之间的区别。然而,它并没有真正解释为什么会有差别,相反,它只是给出了它们是如何不同的例子。 据我所知,一个有一个属性关联的关系是一个关联关系属性,并用一条虚线表示一个圆角矩形,该矩形内有该属性。而关联实体是描述关系的多个属性。两者都只能用于ER图解中的多对多关系。我的思维过程正确吗?

  • 作为条件表达式的结果,我很难获得相关实体对象的列表。我有两个具有多对多关系的对象 但是,这并不像预期的那样有效,因为投影API似乎只支持投影标量属性,而不支持投影实体对象。是否可以通过投影或其他标准API指定这种类型的选择?

  • 我想通过客户端注释获得HttpClient,因此由Micronaut管理。但是,这样我就不能使用属性文件中的url: 是否允许Micronaut管理HttpClient,同时仍然使用来自我的application.yml的url?

  • 我使用Spring Data Neo4J 5.0.10与Spring Boot 2.0.5。节点I具有以下2个实体,用户兴趣实体和用户兴趣实体的关系。 这很有效。我可以创建一个新用户并将该用户与userInterest关联。当我再次发送相同的详细信息时,节点和边不会重复。 当我在关系实体中启用权重属性时,即使权重属性值相同,关系似乎也是重复的。 我记得我读到过,只要属性相同,就不应该创建另一种关系

  • 问题内容: 我有根实体及其单一关联。 当我获取实体时,我需要热切地获取,但是只有它的3个属性:userId,firstName,lastName。 现在,我的条件查询是: 接下来,我得到了sql语句,该语句仅选择投影列表中指定的3个属性。但是它不会选择根实体的任何属性。生成的查询是: 该查询不起作用,因为它返回了五个为空的。五个映射是因为有五行匹配where条件。我创建了简单的sql查询,它工作正