我做一個查詢:點播預先加載
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」急切地加載。它們被定義爲延遲加載,這是我想要的默認行爲,但這是例外情況:我想現在加載它們。我試過換JOIN
爲LEFT 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
您需要發佈您的hibernate映射文件,以查看您是如何禁用延遲加載的 – Karl 2009-11-03 15:52:49
使用示例映射更新的問題。我沒有禁用惰性加載,一切都是懶加載,但是當我做這個特定的查詢時,我希望它急切地加載A的所有屬性,這樣當我循環訪問列表時,我不會收到延遲加載懲罰當訪問它的所有屬性時 – niklassaers 2009-11-03 16:09:56