Hibernate Native SQL 查询检索实体和集合

问题描述 投票:0回答:5

这是我的情况,我有两个基本的 POJO,我给出了一个简单的休眠映射:

Person
  - PersonId
  - Name
  - Books

Book
  - Code
  - Description

我的 SQL 查询返回如下所示的行:

PERSONID NAME       CODE DESCRIPTION
-------- ---------- ---- -----------
1        BEN        1234 BOOK 1
1        BEN        5678 BOOK 2
2        JOHN       9012 BOOK 3

我的休眠查询如下所示:

session.createSQLQuery("select personid, name, code, description from person_books")  
       .addEntity("person", Person.class)
       .addJoin("book", "person.books")
       .list();

这是 hibernate 文档的第 18.1.3 节: http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/querysql.html#d0e17464

我期望在我的列表中得到的是 2 个 Person 对象,其中包含书籍集合中的书籍对象:

List
 |- Ben
 |   |- Book 1
 |   '- Book 2
 '- John
     '- Book 3

我实际看到的是这样的:

List
 |- Object[]
 |   |- Ben
 |   |   |- Book 1
 |   |   '- Book 2
 |   '- Book 1
 |- Object[]
 |   |- Ben
 |   |   |- Book 1
 |   |   '- Book 2
 |   '- Book 2
 '- Object[]
     |- John
     |   '- Book 3
     '- Book 3

有谁知道是否可以使用这种方法得到我想要的东西?

java hibernate native-sql
5个回答
39
投票

扩展马修斯的答案。 要强制休眠仅返回人员列表,请执行以下操作:

List<Person> peopleWithBooks = session.createSQLQuery(
   "select {p.*}, {b.*} from person p, book b where <complicated join>").
     .addEntity("p", Person.class)
     .addJoin("b", "p.books")
     .addEntity("p", Person.class)
     .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
     .list();

关联的 Book 实体将被获取并初始化,无需额外调用数据库。

重复的

 .addEntity("p", Person.class)

是必要的,因为

 .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

对最后添加的实体进行操作。


13
投票

以下对我有用:

session.createSQLQuery("select p.*, b.* from person p, book b where <complicated join>").
.addEntity("person", Person.class).addJoin("book", "person.books").list();

这将返回一个

Object[]
,其中包含
Person
列表,每个列表都包含
Book
列表。它在单个 SQL 选择中完成此操作。我认为你的问题是你没有专门为任何人起别名。

编辑:该方法返回一个 Object[],但数组中填充了 Person 实例,并且仅填充了 Person 实例。

如果 Hibernate 不知道如何映射到您的类,或者不知道如何映射连接,它将返回一个对象列表。确保每行只有一个

Person
/
Book
组合。


7
投票

HHH-2831 使用 addJoin 的本机 SQL 查询或返回对象数组而不是单个实体

此行为是由已知错误引起的。 Doh,应该更努力地搜索!


1
投票

您的查询应该在 person 表上而不是 person_books 上吗?

session.createSQLQuery("select * from person")  
   .addEntity("person", Person.class)
   .addJoin("book", "person.books")
   .list();

1
投票

AFAIK,不可能从 SQL 查询中获取“合并”实体。您将只返回一个对象数组。在这种情况下,我所做的是为合并实体创建一个新的构造函数,该构造函数将对象数组作为其参数。然后我手动构建了它。

© www.soinside.com 2019 - 2024. All rights reserved.