2011-08-25 43 views
16

這是我的情況,我有兩個基本的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 

有誰知道是否有可能得到我想要使用這種方法是什麼?

回答

1

如果您的查詢是在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

12

對我來說,以下工作:

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。那裏沒有任何書。 –

1

AFAIK,從SQL查詢中返回「合併」實體是不可能的。你將只返回一個對象數組。我在這種情況下所做的是,我爲我的合併實體創建了一個新的構造函數,它將參數數組作爲參數。然後我手動構建。

33

在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'的額外子選擇問題。 –