使用join进行Hibernate自定义SQL查询 - 避免返回数组列表

时间:2010-06-25 11:42:46

标签: hibernate

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

为了简化我的情况: -

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的字段。

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

先发制人的评论:是的,我知道我可能会重新构建这个并以不同的方式进行查询(标准API等)。但这就是我现在所困扰的。在这种特殊情况下,我受到其他一些因素的限制,所以希望只是某种方式告诉Hibernate我想要什么!

感谢。

5 个答案:

答案 0 :(得分:1)

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

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

此处id是Entity2的主键

答案 1 :(得分:0)

我没有在我面前进行hibernate测试,看看hibernate手册似乎暗示了这个小变化:

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子句替换SQL中的内连接,即

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

这在语法上等同于hibernate docs中给出的示例。

答案 2 :(得分:0)

查看this是否可以帮助您......

答案 3 :(得分:0)

一种方法是使用Theta-Style连接:

select u from User u join u.permissions p where p.code = :code; 

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

答案 4 :(得分:0)

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

通过JPA,传统的Hibernate API,遗留标准API等,有不同的方法。

如果您使用的是原生SQL,则应该可以通过拨打SQLQuery::addFetch,将您的呼叫替换为addJoin来执行此操作:

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

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