2013-12-18 73 views
0

我有一个运行良好的JBoss的7.1JPA产生额外的SQL对多对一渴望映射

select s FROM Sense s where .... etc 
一个Java对象查询(休眠JPA2)

这个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 ..... 

实体感映射代码:

@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生成用于映射的引用字段这些附加SQLS?这些字段具有EAGER提取类型,但我希望我只能得到一个SQL(第一个有Sense),并且与其他EAGER实体左连接。通过这种方式,当我要求许多Sense对象时,我得到了大量无用的SQL,这需要大量时间来执行。

UPDATE:更改为LAZY帮助,但在离开LAZY是不是我想要的东西 - 这将迫使我改变我所有的DAO的代码。

回答

1

如果你想解决的问题,改了一下您查询,在其中您让自己的内/ LEFT JOINS查询,像:

SELECT s FROM Sense s INNER JOIN FETCH s.domain LEFT JOIN FETCH s.word where... 

使用内/左联接取决于你实体关系(强制/可选)。

几点说明:预先抓取意味着这些关系也牵强,实体返回到您的代码之前,但是,这并不意味着它使一个单一的查询。

+0

我用左手查询连接'选择■从意识的左联接s.domain左连接s.lemma左连接s.partOfSpeech左加入s.senseToSynset'但仍ORM产生这些额外的SQL的。所以现在我有一个选择形式意义,3个左外连接和3个额外的映射实体选择。我需要摆脱这3个额外的选择。使用内部/读取连接也没有帮助。 – Gorky

+0

更新了查询(忘了添加FETCH)... –

+0

当我改为LAZY获取类型并使用JOIN FETCH时,我只有一个sql,所以它的工作!但现在我因为懒惰而被迫改变我的所有代码。有没有解决方案离开EAGER并使用JOIN FETCH来实现我所需要的? – Gorky