2010-06-25 60 views
10

我在Hibernate(3.5.2)中有一个自定义SQL查询,我想在其中返回一个映射对象和一个关联(连接)对象。但是,Hibernate似乎给了我一个数组列表而不是对象列表。加入Hibernate自定义SQL查询 - 避免返回数组列表

为了简化我的情况有点: -

ENTITY1包含一个外键ENTITY2,并映射对象设置,以便ENTITY1有一个对象的属性引用ENTITY2。我想检索一个Entity1对象列表,但关联的对象引用已经被初始化(以便关联的对象已经被加载)。现在

,我可以用自定义的SQL查询这样做:

final SQLQuery qry = hibernateSession.createSQLQuery(
    "select {entity1.*}, {entity2.*} from entity1 inner join entity2 on entity1.fk = entity2.id "); 

qry.setReadOnly(true); 
qry.addEntity("entity1", Entity1.class); 
qry.addJoin("entity2", "entity1.entity2"); 

List list = qry.list(); // Returns list of arrays!! 

这工作,在所有的ENTITY1对象正确初始化。但是,我返回的列表不是Entity1对象的普通列表。它实际上是一个数组列表,其中每个数组包含2个元素 - Entity1和Entity2。我假设这是因为我已经在SELECT子句中放置了两个别名条目。

如果我删除第二个别名(对于Entity2),我只是得到“列未找到”的错误 - 大概是因为Hibernate无法找到字段来初始化entity2。

任何想法?我有一个查询可以返回主要和关联对象的字段,但我希望返回列表只是Entity1对象的列表。

先发制人的评论:是的,我知道我可能可以重新构造这个,并以不同的方式(标准API等)进行查询。但这是我目前所坚持的。在这种特殊情况下,我受到其他一些因素的制约,所以希望有一些方法可以告诉Hibernate我想要什么!

谢谢。

+0

的主键,你specifially要与原生SQL查询要做到这一点,或将HQL吗? – 2013-08-25 20:59:12

+0

您可以使用HQL在未映射的关系上执行内部连接,如下所示:'select * from Entity1 e1,Entity2 e2 where e1.fk = e2.id'。 [这可悲的不适用于外连接](http://stackoverflow.com/questions/9892008/hql-left-join-of-un-related-entities)。 – r0estir0bbe 2014-07-21 11:19:11

+0

在HQL中这很容易,您的查询中哪些内容不能用HQL完成? – 2015-10-09 04:39:49

回答

0

我没有在我面前休眠测试,看着休眠手册似乎表明这个小变化:

final SQLQuery qry = hibernateSession.createSQLQuery(
    "select {entity1.*} from Entity1Table entity1 inner join Entity2Table entity2 on entity1.fk = entity2.id "); 

qry.setReadOnly(true); 
qry.addEntity("entity1", Entity1.class); 
qry.addJoin("entity1.entity2"); 

这应该给你回只是ENTITY1对象,与ENTITY2财产已经初始化。

如果这不起作用,那么请尝试更换内部连接的SQL与where子句,即

select {entity1.*} from Entity1Table entity1, Entity2Table entity2 WHERE entity1.fk = entity2.id "); 

这句法然后等同于休眠文档中给出的示例。

+0

更改连接语法不起作用。从select子句中删除entity2的列只会导致Hibernate抛出“找不到列”错误。 – David 2010-06-25 13:03:59

+0

感谢您的尝试。我感到困惑 - 据我所见,它应该与冬眠文本中的原生SQL示例一样,也会获取带有“dog”属性的“cat”。 – mdma 2010-06-25 17:43:10

+0

注意!有些数据库默认使用交叉连接(示例postgresql)CROSS JOIN子句在两个或多个表中生成行的笛卡尔积。使用“,”与INNER JOIN – 2017-02-02 08:27:39

0

看看this可以帮你......

+0

不同。令人讨厌。但是,这是可行的,是的。 – David 2010-06-25 13:05:07

0

的一种方法是使用θ-风格联接:

权限被映射到用户类的集合。

0

我想你想要的是一个获取连接。这是一个连接,它将数据库中的列转换为对象,但只将这些对象添加到会话缓存中,而不是返回到结果中。

通过JPA,遗留Hibernate API,遗留标准API等,可以做到这一点。

如果您使用的是本地SQL,你应该能够通过调用SQLQuery::addFetch做到这一点,与更换您的来电addJoin

qry.addFetch("entity2", "entity1", "fk"); 

或类似的东西。我必须承认,我不太明白这些参数应该是什么意思,并且我无法通过一些快速搜索找到任何好的文档。

+0

'addFetch'自从Hibernate 3.6以来。问题在于Hibernate 3.5.2。 – xmedeko 2014-03-12 14:48:52

+0

@xmedeko:你说的对,很好。我看不出有什么办法在Hibernate 3.5的'SQLQuery'上进行纯粹的读取连接。 – 2014-03-13 18:05:18

+0

这不起作用。 'addFetch'是'addJoin'的一个更加可定制的变体(但基本相同),因为它返回'FetchReturn'而不是'void'。不幸的是,'FetchReturn'不包含关闭显式返回连接的选项。 – r0estir0bbe 2014-07-21 07:59:46

1

此处实体1(子)包含实体2(父)的外键,实体1(子)类的pojo中应该有一个父类型变量。 我们这是“E”现在查询将是:

Select ent1.* from Entity1 ent1 inner join ent1.E.id 

这里ID是ENTITY2