簡體   English   中英

休眠多人渴望獲取N + 1

[英]Hibernate Many To One eager fetch N+1

我有以下JPA實體:

@Entity
@Table(name = "app")
public class App {

    @Id
    private String id;

    @OneToOne(mappedBy = "app")
    @PrimaryKeyJoinColumn
    private FileDetails fileDetails;

    @ManyToOne
    private Developer developer;

    @ManyToOne
    @JoinColumn(name = "category_id")
    private Category category;

    @OneToMany(mappedBy = "app", fetch = FetchType.EAGER)
    private List<Image> images;

    //getters, setters
}

如您所見,Image實體設置為EAGER fetching。 我想使用分頁選擇所有實體,而我的通用DAO使用此方法:

public List<T> findByPage(int pageNum, int pageSize) {
        CriteriaQuery<T> cq = getEntityManager()
                .getCriteriaBuilder().createQuery(entity);
        cq.select(cq.from(entity));

        int firstResult = pageNum * pageSize;
        return getEntityManager().createQuery(cq)
                .setFirstResult(firstResult)
                .setMaxResults(pageSize)
                .getResultList();
}

但是,當我運行查詢時,與Image實體相關的值為N + 1。 因此,對於每個選擇的應用程序,我都會獲得N個用於選擇圖像的數量。 EAGER提取是否可以解決此問題? 還有什么解決方案?

IIRC,一個joinfetch )以Image在該查詢會解決這個問題。

現在,由於需要指定Image類,因此我將向您展示一個非通用解決方案,以便您可以驗證它是否有效。

// notice I changed all <T> to <App>
public List<App> findByPage(int pageNum, int pageSize) {
        CriteriaQuery<App> cq = getEntityManager()
                .getCriteriaBuilder().createQuery(entity);

        Root<App> root = query.from(App.class); // added this
        root.fetch("app");                      // added this, this is the join

        cq.select(cq.from(entity));

        int firstResult = pageNum * pageSize;
        return getEntityManager().createQuery(cq)
                .setFirstResult(firstResult)
                .setMaxResults(pageSize)
                .getResultList();
}

我不是100%的人(我還沒有測試過,也不知道"app"字符串是否是正確的方式-它應該是您要“拉取”的字段,但是因為有很多一,我不能確定,並放置在現場Image是指App ,而不是),但我認為解決的辦法是周圍某處join ,並在正確的方向希望這點。

暫無
暫無

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

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