在所有嵌套实体中选择几个: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, EntityB
和EntityB
的所有子实体都将被提取,留下EntityC
和EntityD
然后我不知道该怎么做。由于 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<CustomerPartyMappingEntity> findByCustmerId(Integer customerid);
,在这五种不同的情况下,每一种都需要一个不同的嵌套列表,而不是一次全部。所以我认为我应该使用 NamedEntityGraph 来实现这一点。无论如何感谢您的回复。【参考方案2】:
如果您的实体确实设置正确,请参阅子选择示例 here 并删除您的 EAGER(您当前正在指示 hibernate 在实体初始化时获取所有这些字段)。它应该可以工作。
【讨论】:
以上是关于在所有嵌套实体中选择几个:SPRING JPA的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot如何通过查找表将两个实体嵌套在一起而返回另一个实体?
如何使用 Spring Boot 为嵌套实体配置 Jackson 反序列化器