[英]Spring Data JPA + JpaSpecificationExecutor + EntityGraph
[英]Filtering using EntityGraph in Spring Data JPA Repository
我有一个Listing
表至极有一与多的关系ListingAttachment
。 现在在整个应用程序中,每个表/实体都有deleteFlag
,每个存储库只能使用deleteFlag
0获取数据。所以基本上,我们不会删除任何仅将deleteFlag标记为1的数据。
以下是我的实体结构:
Listing.java
@Entity
public class Listing {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
String title;
String description;
@OneToMany(mappedBy = "listing", cascade={CascadeType.ALL})
private Set<ListingAttachment> listingAttachments;
private int deleteFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(int deleteFlag) {
this.deleteFlag = deleteFlag;
}
public Set<ListingAttachment> getListingAttachments() {
return listingAttachments;
}
public void setListingAttachments(Set<ListingAttachment> listingAttachments) {
this.listingAttachments = listingAttachments;
}
public ListingAttachment addListingAttachment(ListingAttachment listingAttachment) {
getListingAttachments().add(listingAttachment);
listingAttachment.setListing(this);
return listingAttachment;
}
public ListingAttachment removeListingAttachment(ListingAttachment listingAttachment) {
getListingAttachments().remove(listingAttachment);
listingAttachment.setListing(null);
return listingAttachment;
}
}
ListingAttachment.java
@Entity
public class ListingAttachment {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
String fileName;
@ManyToOne
@JoinColumn(name = "LISTING_ID")
private Listing listing;
private int deleteFlag;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public Listing getListing() {
return listing;
}
public void setListing(Listing listing) {
this.listing = listing;
}
public int getDeleteFlag() {
return deleteFlag;
}
public void setDeleteFlag(int deleteFlag) {
this.deleteFlag = deleteFlag;
}
}
ListingRepository.java
public interface ListingRepository extends JpaRepository<Listing, Long> {
@EntityGraph(attributePaths = { "listingAttachments" })
@Query("SELECT l FROM Listing l WHERE l.id = (:id) and deleteFlag = 0")
public ListingfindOneWithImagesAndAttachments(@Param("id") Long id);
}
使用EntityGraph,我们可以轻松获取OneToMany实体。 但问题是如何在Many
相关实体上过滤或应用条件。
对于例如,在我的情况,我应该取Listing
与deleteFlag
0及其所有附件(ListingAttachments),这反过来也必须有deleteFlag
0。使用EntityGraph
如上面的资料库,它提取不管所有附件deleteFlag
。 有什么办法可以根据deleteFlag
过滤附件吗?
EntityGraph定义了实体的哪些属性或(子)图应该被提取(急切或懒惰),而不必在实体本身上定义它们。
在JPA 2.0(没有EntityGraph)中,您必须在实体中定义是否要使用FetchType.LAZY
(默认值)或FetchType.EAGER
来加载关系,并始终使用此模式。
使用EntityGraph,您可以为每个查询定义属性和(子)图。
EntityGraph不用于过滤元素。
如果您要查找的Listings
为删除未标明( delete flag = 0
),并且至少有一个ListingAttachment
没有被标记为删除,你可以通过使用一个做到这一点FETCH JOIN
public interface ListingRepository extends JpaRepository<Listing, Long> {
@EntityGraph(attributePaths = { "listingAttachments" })
@Query("SELECT l FROM Listing l JOIN l.listingAttachments a
WHERE l.id = (:id) and l.deleteFlag = 0 and a.deleteFlag = 0")
public Listing findOneWithImagesAndAttachments(@Param("id") Long id);
}
你需要加入ListingAttachments
,因为你不能直接取消引用deleteFlag
使用的JPA查询listingAttachments
收藏。
上面的示例返回所有未标记为已删除的列表,并且至少有一个未标记为已删除的ListingAttachment。
如果要返回未标记为已删除但可能没有ListingAttachments的列表,则必须将其更改为LEFT OUTER JOIN
@Query("SELECT l FROM Listing l
LEFT OUTER JOIN l.listingAttachments a
WHERE l.id = (:id) and l.deleteFlag = 0 and a.deleteFlag = 0")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.