【问题标题】:JPA Entity that has a OneToMany relationship and want to use DTO具有 OneToMany 关系并希望使用 DTO 的 JPA 实体
【发布时间】:2021-02-26 13:52:06
【问题描述】:

我有一个名为“Review”的实体,它与“User”实体具有 OneToOne 关系,与“ReviewStage”实体具有 OneToMany 关系。我已经实现了 DTO 模式,所以我也有 ReviewDTO,它实际上是发送到 UI 的内容。我正在使用 mapstruct 将实体映射到 dto。一切运行良好,但我宁愿在关系映射中使用 UserDTO 和 ReviewStageDTO。

这很好用:

@Entity
@Getter @Setter @NoArgsConstructor
public class Review {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long reviewId;
    
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "ownerId")
    private User owner;

    @OneToMany(mappedBy = "reviewId")
    private Set<ReviewStage> stages;

}

为了好玩,我尝试了这个,但显然不起作用:

@Entity
@Getter @Setter @NoArgsConstructor
public class Review {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long reviewId;
    
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "ownerId")
    private UserDTO owner;

    @OneToMany(mappedBy = "reviewId")
    private Set<ReviewStageDTO> stages;

}

我只需要朝着正确的方向轻推。谢谢,

【问题讨论】:

    标签: java spring-boot hibernate jpa mapstruct


    【解决方案1】:

    relationships 应该只在entities 之间,如果你想为Review 创建一个dto 并且在这个dto 里面你想返回UserDto 例如你应该创建一个@987654327 @ 在UserEntityUserDTO 之间映射

    示例

    class UserDto {
        /// put any fields here that you want to map
    }
    
    class ReviewDto {
        UserDto user;
    }
    
    @Mapper(componentModel = "spring")
    class UserMapper {
        UserDto map(User user);
    }
    
    @Mapper(componentModel = "spring", uses={UserMapper.class})
    class ReviewMapper {
        ReviewDto map(Review review);
    }
    

    【讨论】:

    • 好的,我明白了——超级简单。在我的评论实体中,我不理会“私人用户所有者”。在我的 ReviewDTO 中,我使用“私人 UserDTO 所有者”。我已经定义了所有的 mapstruct 接口,所以效果很好。我对 Set 做了同样的事情。谢谢。
    【解决方案2】:

    如果您担心性能,我可以建议您看看Blaze-Persistence Entity Views 提供的内容。

    我创建了该库以允许在 JPA 模型和自定义接口或抽象类定义模型之间轻松映射,例如 Spring Data Projections on steroids。这个想法是您按照自己喜欢的方式定义目标结构(域模型),并通过 JPQL 表达式将属性(getter)映射到实体模型。

    使用 Blaze-Persistence Entity-Views 的用例的 DTO 模型可能如下所示:

    @EntityView(Review.class)
    public interface ReviewDTO {
        @IdMapping
        Long getReviewId();
        UserDTO getOwner();
        Set<ReviewStageDTO> getStages();
    
        @EntityView(User.class)
        interface UserDTO {
            @IdMapping
            Long getId();
            String getName();
        }
    
        @EntityView(ReviewStage.class)
        interface ReviewStageDTO {
            @IdMapping
            Long getId();
            String getName();
        }
    }
    

    查询是将实体视图应用于查询的问题,最简单的就是通过 id 进行查询。

    ReviewDTO a = entityViewManager.find(entityManager, ReviewDTO.class, id);

    Spring Data 集成让您可以像使用 Spring Data Projections 一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

    Optional<ReviewDTO> findByReviewId(long reviewId);
    

    请注意,这只会获取实际需要的状态。使用 MapStruct 或其他 bean 映射解决方案,您必须自己处理有效的获取。

    【讨论】:

      猜你喜欢
      • 2016-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多