2009-11-03 90 views
3

我做一個查詢:點播預先加載

String query = "SELECT DISTINCT a FROM A a FETCH ALL PROPERTIES " + 
     "JOIN a.Bs AS b " + 
     "JOIN b.Cs AS c WHERE c = :c"; 
Query q = DAO.getSession().createQuery(query); 
q.setParameter("c", c); 
return q.list(); 

即使我已經說過FETCH ALL PROPERTIES上,當我訪問A有,他們仍然需要加載的所有藏書,因此AREN」急切地加載。它們被定義爲延遲加載,這是我想要的默認行爲,但這是例外情況:我想現在加載它們。我試過換JOINLEFT OUTER JOIN來挑起Hibernate來加載它們,我試過設置q.setFetchMode("a", FetchMode.EAGER),但它不存在Query。

As的列表相當長,並且它們有很多集合,所以使得這個n + 1查詢的事情非常緩慢(大約十秒鐘,而不是在一個單獨的查詢中進行) - 第二速度)。我更喜歡一個查詢並加載所有必要的查詢。有關如何做到這一點的任何建議?

PS,小獎金的問題:如果我有"WHERE :c IN b.Cs";更換"JOIN b.Cs AS c WHERE c = :c"; 線,我得到一個SQL異常:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '))' at line 1 

雙paranthesis它指的是「與( '151000000-0000' 在(。 ))「其中151000000-0000是c的主鍵。任何想法,當我這樣做時,爲什麼我會得到這個錯誤,而不是當我這樣做時加入b.Cs?

更新,根據要求,這裏是我用於映射的方式。 B和C是非常相似的設計:

@Entity 
@Table(name = "tblA") 
public class A { 
    @Id 
    String AId; 

    @Column(name = "shortName", length = 12, nullable = false) 
    String shortName; 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="theA") 
    private Set<B> Bs; 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="theA") 
    private Set<D> Ds; 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="theA") 
    private Set<E> Es; 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="theA") 
    private Set<F> Fs; 
} 

THEA在B,d,E和F的定義如下:

@ManyToOne(fetch=FetchType.LAZY) 
@JoinColumn(name = "AId", nullable = true) 
@ForeignKey(name="FK_KategoriID") 
private A theA; 

乾杯

的Nik

+0

您需要發佈您的hibernate映射文件,以查看您是如何禁用延遲加載的 – Karl 2009-11-03 15:52:49

+0

使用示例映射更新的問題。我沒有禁用惰性加載,一切都是懶加載,但是當我做這個特定的查詢時,我希望它急切地加載A的所有屬性,這樣當我循環訪問列表時,我不會收到延遲加載懲罰當訪問它的所有屬性時 – niklassaers 2009-11-03 16:09:56

回答

8

fetch all properties是不是你想要的;它用於告訴Hibernate你希望它獲取單值的延遲加載的屬性。詳情是here

您需要在您的查詢指定join fetch代替:

SELECT DISTINCT a FROM A a 
    LEFT JOIN FETCH a.Bs AS b 
    LEFT JOIN FETCH b.Cs AS c 
WHERE c = :c 

至於獎金問題去,WHERE :c IN b.Cs是非法的語法。根據您的C映射的方式,您可能需要查看elements()函數。

+0

啊,我沒有發現有關單值延遲加載的問題。感謝關於LEFT JOIN FETCH的提示:-) – niklassaers 2009-11-03 17:58:34

+0

我知道這是舊的但鏈接已損壞:-) – porfiriopartida 2013-10-07 17:08:56

+1

@porfiriopartida - 鏈接是固定的 – ChssPly76 2013-10-07 17:36:07