我有一个java对象查询(hibernate jpa2),可以在JBoss 7.1中正常运行
select s FROM Sense s where .... etc
此SQL出现在Jboss控制台中:
select
sense0_.id as id12_,
sense0_.domain as domain12_,
sense0_.lemma as lemma12_,
sense0_.part_of_speech as part5_12_,
sense0_.sense_number as sense2_12_
from sense sense0_
where ...
这是正确的
但是,在Jboss控制台中还出现了大量与'Sense'属性相关的查询, 这些字段是对其他实体的引用,例如 Domain,Word,PartOfSpeach。
select domain0_.id as id5_0_, domain0_.description as descript2_5_0_,
domain0_.name as name5_0_ from domain ....
select word0_.id as id19_2_, word0_.id_lexicon as id3_19_2_ from word
word0_ ....
select partofspee0_.id as id9_2_, domains1_.id_pos as id1_9_4_ from
part_of_speech partofspee0 .....
实体代码Sense mapping:
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="domain", referencedColumnName="id", nullable = false)
private Domain domain;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="lemma", referencedColumnName="id", nullable = false)
private Word lemma;
@ManyToOne(fetch=FetchType.EAGER)
@JoinColumn(name="part_of_speech", referencedColumnName="id", nullable = false)
private PartOfSpeech partOfSpeech;
为什么JPA会为映射引用字段生成这些额外的SQL?这些字段具有EAGER提取类型,但我希望我只能获得一个SQL(第一个使用Sense)和左连接其他EAGER实体。这样,当我要求许多Sense对象时,我会得到大量无用的SQL,这需要大量的时间来执行。
更新:改为LAZY有帮助,但离开LAZY并不是我想要的 - 这会迫使我改变我所有的dao代码。
答案 0 :(得分:1)
如果您想解决问题,请更改您查询的位,在该位置中您将自己设置为查询中的INNER / LEFT JOINS,如:
SELECT s FROM Sense s INNER JOIN FETCH s.domain LEFT JOIN FETCH s.word where...
根据您的实体关系使用内/左连接(强制/可选)。
一些解释:EAGER FETCH意味着在实体返回到您的代码之前也会获取这些关系,但这并不意味着它会进行单个查询。