簡體   English   中英

如何在 JpaRepository 中定義自定義 findAll 方法?

[英]How to define custom findAll methods in JpaRepository?

我有兩個 api 端點:

  • /api/posts - 獲取分頁帖子列表
  • /api/countries/{country}/posts - 按國家/地區獲取分頁帖子列表

所以我有以下實體:

@Data
@Entity
@Table(name = "posts")
@EntityListeners(AuditingEntityListener.class)
@NamedEntityGraph(
    name = "Post.Resource",
    attributeNodes = @NamedAttributeNode("country")
)
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String title;
    private String body;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "country_id")
    private Country country;

    @Column(name = "published_at")
    private LocalDateTime publishedAt;

    @CreatedDate
    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @LastModifiedDate
    @Column(name = "updated_at")
    private LocalDateTime updatedAt;

    public boolean isPublished() {
        return publishedAt != null;
    }

    public boolean isDraft() {
        return !isPublished();
    }
}

我已經定義了以下存儲庫。 請注意,我是如何為最后兩個方法定義實體圖的,我需要這樣,因為我不想覆蓋findAll()方法,因為將來我需要加載沒有任何關系的帖子。 還有一件事我希望它成為謂詞,以便在各種不同的服務中我可以重用方法,而不是為每個查詢創建方法......

@Repository
public interface PostRepository extends JpaRepository<Post, Long>, 
    JpaSpecificationExecutor<Post>, 
    QuerydslPredicateExecutor<Post> 
{
    @EntityGraph("Post.Resource")
    Optional<Post> findPostResourceById(long id);

    @Query("SELECT post FROM Post post")
    @EntityGraph("Post.Resource")
    Page<Post> findAllPostResources(Pageable pageable);

    @Query("SELECT post FROM Post post")
    @EntityGraph("Post.Resource")
    Page<Post> findAllPostResources(Predicate predicate, Pageable pageable);
}

問題是當我使用謂詞和可分頁 arguments 調用findAllPostResources時:

public Page<Post> getAllPostsByCountryPaginated(long countryId, Pageable pageable) {
    return postRepository.findAllPostResources(QPost.post.country.id.eq(countryId), pageable);
}

它忽略謂詞參數並執行以下查詢:

SELECT
    post0_.id AS id1_13_0_,
    country1_.id AS id1_3_1_,
    post0_.body AS body2_13_0_,
    post0_.country_id AS country_7_13_0_,
    post0_.created_at AS created_3_13_0_,
    post0_.published_at AS publishe4_13_0_,
    post0_.title AS title5_13_0_,
    post0_.updated_at AS updated_6_13_0_,
    country1_.alpha2_code AS alpha2_3_1_,
    country1_.alpha3_code AS alpha3_3_1_,
    country1_.created_at AS created_4_3_1_,
    country1_.name AS name5_3_1_,
    country1_.updated_at AS updated_6_3_1_
FROM
    posts post0_
LEFT OUTER JOIN countries country1_ ON
    post0_.country_id = country1_.id
LIMIT ?

如您所見, SQL ( WHERE country_id =? )中沒有 WHERE 原因。

那么,如何創建 findAll() 方法並定義謂詞、分頁以及在 JpaRepository 中使用什么實體圖? 或者這是無法通過這種方式實現的,我需要創建自定義存儲庫實現?

但你有這個查詢:

LEFT OUTER JOIN countries country1_ ON
    post0_.country_id = country1_.id
LIMIT

與“where country_id =”不一樣嗎? 您是否在示例數據庫上運行此查詢並查看您得到了什么? 也許它只是工作正常。

另外,我認為,你可以說

findAllPostResourcesByCountryId(long countryId);

抱歉,我很想發表評論而不是回答,但我沒有足夠的聲譽。

我找到了解決我的問題的方法:如何同時使用 Predicate、Pageable 和 EntityGraph 的方法,答案是使用以下庫:

https://github.com/Cosium/spring-data-jpa-entity-graph

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM