21

这是我的情况,我有两个基本的 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();

这是每个部分:休眠文档的 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

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

4

5 回答 5

38

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

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();

无需额外调用 db 即可获取和初始化关联的 Book 实体。

复制品

 .addEntity("p", Person.class)

是必要的,因为

 .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)

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

于 2013-06-20T10:00:13.437 回答
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,每个列表都包含一个Books 的列表。它在单个 SQL 选择中执行此操作。我认为您的问题是您没有专门将 person 别名为任何东西。

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

如果 Hibernate 不理解如何映射到您的类,或者如果它不理解如何映射连接,它将返回一个对象列表。确保每行只有一个Person/Book组合。

于 2011-08-25T11:40:36.377 回答
7

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

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

于 2011-08-26T02:01:30.150 回答
1

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

session.createSQLQuery("select * from person")  
   .addEntity("person", Person.class)
   .addJoin("book", "person.books")
   .list();
于 2011-08-25T08:07:40.960 回答
1

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

于 2011-08-26T02:21:07.473 回答