nik*_*ers 3 java hibernate lazy-loading
我提出一个问题:
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();
Run Code Online (Sandbox Code Playgroud)
即使我已经说过FETCH ALL PROPERTIES,当我访问A所有的集合时,它们仍然需要加载,因此不会急切加载.它们被定义为延迟加载,这是我想要的默认行为,但这是例外:我希望它们现在加载.我试着换JOIN了LEFT OUTER JOIN挑起休眠到加载它们,我尝试了设定q.setFetchMode("a", FetchMode.EAGER),但它并不适用于查询存在.
As的列表很长,而且它们有很多集合,所以这个n + 1查询的东西非常慢(大约十秒,而不是在单个查询中进行,这将是亚秒速度) .我更喜欢一个查询并加载所有必要的内容.有关如何做到这一点的任何建议?
PS,小小的奖励问题:如果我替换了这一"JOIN b.Cs AS c WHERE c = :c";
行"WHERE :c IN b.Cs";,我得到一个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
Run Code Online (Sandbox Code Playgroud)
它所指的双重语句是"和('(151000000-0000'in(.))"其中151000000-0000是主键c.知道为什么我这样做的时候会出现这个错误,相比之下我加入b.Cs时没有得到它?
UPDATE,根据要求,这是我用于映射的方式.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;
}
Run Code Online (Sandbox Code Playgroud)
B,D,E和F中的A定义如下:
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name = "AId", nullable = true)
@ForeignKey(name="FK_KategoriID")
private A theA;
Run Code Online (Sandbox Code Playgroud)
干杯
聂
fetch all properties不是你想要的; 它用于告诉Hibernate你希望它获取单值的延迟加载属性.细节在这里.
您需要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
Run Code Online (Sandbox Code Playgroud)
至于奖金问题,WHERE :c IN b.Cs是非法语法.根据您C的映射方式,您可能希望查看elements()函数.
| 归档时间: |
|
| 查看次数: |
6324 次 |
| 最近记录: |