休眠本地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,应该更努力地搜索!
如果您的查询是在person table而不是person_books上?
session.createSQLQuery("select * from person")
.addEntity("person", Person.class)
.addJoin("book", "person.books")
.list();
为简洁起见,我简化了这个例子。在我的实际使用中,“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
组合。
我期待的是一个Person列表,而不是一个拥有多个人的重复对象的列表,当他们拥有多本书时。查看我的答案以获得有关hibernate jira bug报告的链接。 – Ben
对不起,为了让自己清楚,该方法返回一个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)
操作,并且在最后的实体加入。
这将为个人和书籍获取所有内容。如果您只想选择某些属性来提高性能,该怎么办?据我所知除了*或p。*以外的任何内容都不起作用。 – T3rm1
使用'{p。*},{b。*}'还修复了'books'的额外子选择问题。 –
更新:更正链接。 @ehrhardt回答为Hibernate 5.1修复了这个问题:http://stackoverflow.com/a/17210746/3405171 –