使用的休眠版本:
<artifactId>hibernate-annotations</artifactId>
<version>3.5.5-Final</version>
<artifactId>hibernate-core</artifactId>
<version>3.5.5-Final</version>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.2.0.Final</version>
<artifactId>hibernate-jpa-2.0-api</artifactId>
<version>1.0.0.Final</version>
假设有两只猫(猫和它的伴侣有相同的小猫)猫/猫的伴侣与它的小猫有关系,小猫的名字作为连接列(连接列上的 OneToMany 关系,获取类型为“eager”)
假设我想得到小猫名字为“大”的猫,为此,我可以用不同的方式编写 hql。
I.
hql.append("from Cat as cat ")
hql.append("where cat.kitten.name = 'big' ");
II.
hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.name = 'big' ");
前面提到的 hql 在 cat 和它的小猫之间生成了一个内部连接,并且按预期工作。
但是,如果我想查询 kitten 中的一个属性,其中 cat 没有加入 kitten (比如 location ),我可以编写 hql 如下:
III.
hql.append("from Cat as cat ")
hql.append("where cat.kitten.location = 'Chicago' ");
IV.
hql.append("from Cat as cat inner join cat.kitten as kitten ")
hql.append("where kitten.location = 'Chicago' ");
问题 1) III 和 IV 也按预期工作,但是,III 正在 cat 和它的小猫之间生成笛卡尔/交叉连接,而没有 hql 中提到的显式连接,而 IV 不是。这是为什么?
和
说,我想在 hql 中加入两个“不同”的对象 cat 和 mate (没有任何关联),它正在生成交叉连接。
例如,如果我说,
V.
hql.append("select cat ")
hql.append("from Cat as cat, Mate mate ")
hql.append("where cat.location = mate.location and mate.location = 'Chicago' ");
它生成交叉连接。
但是,如果我说,
VI.
hql.append("from Cat as cat ")
hql.append("where cat.location in ( select mate.location from Mate mate where mate.location = 'Chicago' ");
问题 2)它不会生成交叉连接。但是,如果我必须使用两列怎么办。我需要使用两个 in 子句才能没有由 hql 生成的交叉连接。为什么一定要明确?或者如果可能的话,是否有休眠配置来避免交叉连接?