2009-11-03 74 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