2014-05-07 31 views
0

我有以下的JPA實體:Hibernate的多對一​​急於取N + 1

@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 
} 

正如你可以看到圖像實體設置爲EAGER抓取。 我想用分頁選擇所有實體和我一般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(); 
} 

然而,當我運行查詢我有N + 1相對於圖像實體。因此,對於每個選擇的應用程序,我都會選擇N個圖像的數量。 Isnt EAGER抓取應該解決這個問題?什麼可能是一個解決方案?

回答

1

IIRC,a 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%對這個(我have't測試,不知道是否"app"字符串是正確的方式 - 它應該是要「拉」的領域,但因爲這是多對一,我不能確定,並放置在Image引用App代替)的領域,但我認爲解決的辦法是某處大約在正確的方向上join希望這點。

相關問題