在所有嵌套实体中选择几个:SPRING JPA

Posted

技术标签:

【中文标题】在所有嵌套实体中选择几个:SPRING JPA【英文标题】:Select few among all the nested entities : SPRING JPA 【发布时间】:2020-08-02 06:44:30 【问题描述】:

我有一个像下面这样的场景。

假设EntityA 有三个嵌套实体EntityB, EntityC, EntityD。并且所有EntityB, EntityC, EntityD 内部都有几个嵌套实体。

但在选择EntityA 时,它会选择整个嵌套实体树。而我想获取特定的分支。可以说只有EntityA, EntityBEntityB 的所有子实体都将被提取,留下EntityCEntityD 然后我不知道该怎么做。由于 spring jpa 将所有嵌套对象都带回给我。

我正在使用以下集合映射。


 @Entity
 @Table(name = "customer_party_mapping")
 @Data
 public class CustomerPartyMappingEntity 
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Integer id;
    
    @Column(name = "customer_id")
    private Integer custmerId;
    
    @Column(name = "orgtype_id")
    private Integer orgTypeId;
    
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerPartyBookingLocationEntity> customerPartyBookingLocation=new ArrayList<CustomerPartyBookingLocationEntity>();
    
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerPartyFieldMappingEntity> customerPartyFieldMappingEntity=new ArrayList<CustomerPartyFieldMappingEntity>();

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id",referencedColumnName="id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerPartyOtherDocumentEntity> otherDocumentsList=new 
    ArrayList<>();
    
    @OneToOne( cascade= CascadeType.PERSIST, CascadeType.MERGE )
    @JoinColumn(name = "customer_name_screening_id", referencedColumnName="id") 
    private CustomerNameScreeningEntity customerNameScreeningEntity;
        
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL )
    @JoinColumn(name = "customer_party_mapping_id")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<CustomerDocInfoTrackingEntity> customerDocInfoTrackingList=new 
    ArrayList<CustomerDocInfoTrackingEntity>();


我正在打电话


List<CustomerPartyMappingEntity> customerPartyMappingEntityList = customerPartyMappingRepository.findByCustmerId(customerid);

它获取所有嵌套映射的实体列表,而我只需要CustomerPartyMappingEntity 及其customerPartyFieldMappingEntity 嵌套对象列表。

我们将不胜感激。

【问题讨论】:

【参考方案1】:

首先将FetchType.LAZY 用于嵌套实体。 然后,您可以使用@EntityGraph 按名称获取嵌套实体,并在存储库中使用其名称和. 获取嵌套实体。您可以在 attributePaths 中指定嵌套属性,例如

@EntityGraph(attributePaths = "customerPartyBookingLocation")

customerPartyBookingLocation的嵌套属性一样

@EntityGraph(attributePaths = "customerPartyFieldMappingEntity.subField")

例子:

@EntityGraph(attributePaths = "customerPartyBookingLocation", "customerPartyFieldMappingEntity.subField")
List<CustomerPartyMappingEntity> findByCustmerId(Integer customerid);

注意:您不能将@EntityGraph 与@Query 注释一起使用

【讨论】:

好的。然后,如果我想要检索嵌套集合的不同组合,那么我必须在存储库中有多个类似的方法吗?如果是这样,那么我不能对根实体使用派生查询,而必须使用@Query 方式.. 对吗? @EntityGraph不能和@Query一起使用,可以用方法命名查询和@EntityGraph一起使用 我不确定您所说的“方法命名查询”是什么意思。你是说 NamedEntityGraph 吗? 不,其实我的意思是Query creation from method names 我认为“从方法名称创建查询”和派生查询之间没有太大区别。它们在以下用例中都没有用。假设我仍然想在五种不同的情况下调用List&lt;CustomerPartyMappingEntity&gt; findByCustmerId(Integer customerid);,在这五种不同的情况下,每一种都需要一个不同的嵌套列表,而不是一次全部。所以我认为我应该使用 NamedEntityGraph 来实现这一点。无论如何感谢您的回复。【参考方案2】:

如果您的实体确实设置正确,请参阅子选择示例 here 并删除您的 EAGER(您当前正在指示 hibernate 在实体初始化时获取所有这些字段)。它应该可以工作。

【讨论】:

以上是关于在所有嵌套实体中选择几个:SPRING JPA的主要内容,如果未能解决你的问题,请参考以下文章

Spring:嵌套实体保存空值问题

Spring Boot如何通过查找表将两个实体嵌套在一起而返回另一个实体?

如何使用 Spring Boot 为嵌套实体配置 Jackson 反序列化器

Spring框架 之@Valid注解的使用(嵌套类型的效验)

如何按包含的实体搜索/选择,但将所有相关实体包含到结果集中

Spring Data Rest - 按嵌套属性排序