休眠本地SQL查询检索的实体和集合

问题描述:

这是我的情况,我有两个基本的POJO的,我已经给了一个简单的Hibernate映射:休眠本地SQL查询检索的实体和集合

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 

我的Hibernate查询是这样的:

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人与书所载物体的藏书中的对象:

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 

有谁知道是否有可能得到我想要使用这种方法是什么?

HHH-2831 Native SQL queries with addJoin or return object arrays instead of single Entities

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

+0

更新:更正链接。 @ehrhardt回答为Hibernate 5.1修复了这个问题:http://*.com/a/17210746/3405171 –

如果您的查询是在person table而不是person_books上?

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

为简洁起见,我简化了这个例子。在我的实际使用中,“person_books”是一个复杂的查询,如果没有我在查询中提供它,hibernate无法获取“书”的信息。我正在为Person检索大量行,并且不希望执行额外的查询来为每个人查找书籍。如果我找不到解决方案,我可能会使用此方法,但只是跳过Person不更改的行。 – Ben

对我来说,以下工作:

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

这将返回包含Person列表的Object[],每个都包含的Book的List。它在单个SQL选择中执行此操作。我认为你的问题在于你没有专门给任何人别名。

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

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

+0

我期待的是一个Person列表,而不是一个拥有多个人的重复对象的列表,当他们拥有多本书时。查看我的答案以获得有关hibernate jira bug报告的链接。 – Ben

+0

对不起,为了让自己清楚,该方法返回一个Object [],但该数组填充了Person,并且仅填充了Person。那里没有任何书。 –

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

在Mathews答案上展开。 来强制Hibernate只返回的人员名单做:

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

关联图书实体将被获取并没有到一个数据库中的额外的呼叫初始化。

重复的

.addEntity("p", Person.class) 

是必要的,因为

.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 

操作,并且在最后的实体加入。

+1

这将为个人和书籍获取所有内容。如果您只想选择某些属性来提高性能,该怎么办?据我所知除了*或p。*以外的任何内容都不起作用。 – T3rm1

+1

使用'{p。*},{b。*}'还修复了​​'books'的额外子选择问题。 –