2010-12-21 36 views
0

首先,這是我第一次使用Hibernate,所以我的問題可能看起來很幼稚。Hibernate外鍵關係--list()使得不必要的sql查詢 - setMaxResults被忽略

我有兩個表,DsJobs和DsEvents。事件在DsJobs表上具有外鍵關係(DsJobs表中的EID列對應於DsEvents表的ID列)。

我已經creted與anotations映射,我關心的是單方面的關係,所以我必須用@ManyToOne註釋DsJobs表「dsEvents」屬性:

@Entity 
@Table(name="DsJobs") 
public class DsJobs implements java.io.Serializable { 

... 

    private DsEvents dsEvents; 
    ... 

    @Id 
    @Column(name="JID", unique=true, nullable=false) 
    public long getJid() { 
     return this.jid; 
    } 

    public void setJid(long jid) { 
     this.jid = jid; 
    } 

@ManyToOne 
    @JoinColumn(name="eid") 

    public DsEvents getDsEvents() { 
     return this.dsEvents; 
    } 

    public void setDsEvents(DsEvents dsEvents) { 
     this.dsEvents = dsEvents; 
    } 
.... 
} 

我想要檢索的列表作業從數據庫記錄並使用setFirstResult和setMaxResults限制它們。這是呼叫我做:

return (ArrayList<DsJobs>) this.sessionFactory.getCurrentSession().createQuery("from DsJobs log").setFirstResult(start).setMaxResults(rows).list(); 

此代碼返回DsJobs對象的ArrayList和內部的每DsJobs對象是有DsEvents對象,正確實例。

我的問題有兩個:

  1. 當我看到HQL執行有unnecesery選擇到數據庫中,一個爲每DsJobs通話錄音。因此,對於每個DsJobs記錄,DsEvents中都有一個SELECT來通過事件ID獲取相應的事件。這對於性能來說是不可接受的,因爲使用簡單的JDBC,我可以通過內部連接SELECT stament獲取所需的所有數據。我可能在做一些完全錯誤的事情,請告訴我什麼,如果你知道我應該怎麼做。

  2. setFirstResult和setMaxResults似乎完全被Hibernate忽略,我總是從數據庫中獲取所有記錄。我該如何解決這個問題?

我將非常感謝任何幫助。

預先感謝您。

回答

1

當我看到HQL執行時,有不必要的SELECT調用到數據庫,每個DsJobs記錄有一個。

是的,這是可怕的n + 1選擇問題。只有當您對關係執行一些RI約束(例如,一對一,或唯一約束)時纔會發生這種情況。您向我們展示的地圖似乎沒有這些問題,這使我認爲您沒有向我們展示造成您麻煩的實際地圖。請張貼實際的代碼,而不是一些通用的縮寫版本。

setFirstResult和setMaxResults似乎被Hibernate完全忽略,我總是從數據庫中獲取所有記錄。我該如何解決這個問題?

此代碼也很好。這意味着你沒有向我們展示導致你麻煩的實際代碼。

+0

這正是我的問題,謝謝你的回答。我沒有完全理解爲什麼會發生這種情況,但我能夠解決第一個問題:從DsJobs日誌左連接抓取log.dsEvents。 – alex 2010-12-23 06:35:58