我有两个HQL查询用于快速和脏的单元测试。第一个看起来有点像这样:
from Foo where SOME_FOREIGN_KEY = 42
第二个看起来像这样:
from Foo as foo
inner join foo.Bar as bar
where foo.SOME_FOREIGN_KEY = 42
SOME_FOREIGN_KEY列不是Hibernate知道的映射名称。
由于某种原因,第一个HQL查询有效,但第二个没有。
我的目标是让第二个版本工作,而无需将对象图遍历到外键标识的对象。对于此测试,我有一个已知的ID,我只想要与该ID相关的对象。关系另一端的对象本身是无关紧要的。这可能吗?
答案 0 :(得分:8)
由于某种原因,第一个HQL查询有效,但第二个没有。
当您在HQL查询的WHERE
子句中使用Hibernate不知道的内容时(例如,未在SQL方言中注册的函数),Hibernate行为灵巧,直接传递它到数据库。
换句话说,假设Foo
映射到TABLE_FOO
,则以下HQL
from Foo where SOME_FOREIGN_KEY = 42
被翻译成以下SQL
SELECT FROM TABLE_FOO WHERE SOME_FOREIGN_KEY = 42
如果TABLE_FOO
实际上有SOME_FOREIGN_KEY
列,则可以使用。
但是,在使用第二个示例中的别名时:
from Foo as foo where foo.SOME_FOREIGN_KEY = 42
Hibernate尝试将SOME_FOREIGN_KEY
解析为Foo
实体的属性,这显然会失败。
我的目标是让第二个版本正常工作,而无需将对象图遍历到外键标识的对象。
如果您在列前添加别名,则不会。所以以下内容应该有效:
from Foo as foo
inner join foo.Bar as bar
where SOME_FOREIGN_KEY = 42
但老实说,我不明白为什么你不想使用路径表达式,我建议不要使用上述解决方案。 HQL的一个重点是抽象表名和列名,你将在这里完全击败这个目标。
答案 1 :(得分:1)
所以第一个例子中的Foo没有别名,第二个例子就是。这意味着在第二个例子中,Hibernate正在寻找'foo'的属性。这应该是答案。
也许这会奏效:
select f
from Foo f
inner join f.Bar bar
where f.SomeForeignKeyId = 42
SomeForeignKeyId是映射到SOME_FOREIGN_KEY的属性,无论哪种方式,您都必须通过引用实体的Id字段执行此操作。
同样在第一个示例中获取Foo,应该可以正常工作,具体取决于您的映射。因此,如果在您的映射中您有Eager提取,那么这应该是我所知道的。