2010-06-25 63 views
10

我在Hibernate(3.5.2)中有一個自定義SQL查詢,我想在其中返回一個映射對象和一個關聯(連接)對象。但是,Hibernate似乎給了我一個數組列表而不是對象列表。加入Hibernate自定義SQL查詢 - 避免返回數組列表

爲了簡化我的情況有點: -

ENTITY1包含一個外鍵ENTITY2,並映射對象設置,以便ENTITY1有一個對象的屬性引用ENTITY2。我想檢索一個Entity1對象列表,但關聯的對象引用已經被初始化(以便關聯的對象已經被加載)。現在

,我可以用自定義的SQL查詢這樣做:

final SQLQuery qry = hibernateSession.createSQLQuery(
    "select {entity1.*}, {entity2.*} from entity1 inner join entity2 on entity1.fk = entity2.id "); 

qry.setReadOnly(true); 
qry.addEntity("entity1", Entity1.class); 
qry.addJoin("entity2", "entity1.entity2"); 

List list = qry.list(); // Returns list of arrays!! 

這工作,在所有的ENTITY1對象正確初始化。但是,我返回的列表不是Entity1對象的普通列表。它實際上是一個數組列表,其中每個數組包含2個元素 - Entity1和Entity2。我假設這是因爲我已經在SELECT子句中放置了兩個別名條目。

如果我刪除第二個別名(對於Entity2),我只是得到「列未找到」的錯誤 - 大概是因爲Hibernate無法找到字段來初始化entity2。

任何想法?我有一個查詢可以返回主要和關聯對象的字段,但我希望返回列表只是Entity1對象的列表。

先發制人的評論:是的,我知道我可能可以重新構造這個,並以不同的方式(標準API等)進行查詢。但這是我目前所堅持的。在這種特殊情況下,我受到其他一些因素的制約,所以希望有一些方法可以告訴Hibernate我想要什麼!

謝謝。

+0

的主鍵,你specifially要與原生SQL查詢要做到這一點,或將HQL嗎? – 2013-08-25 20:59:12

+0

您可以使用HQL在未映射的關係上執行內部連接,如下所示:'select * from Entity1 e1,Entity2 e2 where e1.fk = e2.id'。 [這可悲的不適用於外連接](http://stackoverflow.com/questions/9892008/hql-left-join-of-un-related-entities)。 – r0estir0bbe 2014-07-21 11:19:11

+0

在HQL中這很容易,您的查詢中哪些內容不能用HQL完成? – 2015-10-09 04:39:49

回答

0

我沒有在我面前休眠測試,看着休眠手冊似乎表明這個小變化:

final SQLQuery qry = hibernateSession.createSQLQuery(
    "select {entity1.*} from Entity1Table entity1 inner join Entity2Table entity2 on entity1.fk = entity2.id "); 

qry.setReadOnly(true); 
qry.addEntity("entity1", Entity1.class); 
qry.addJoin("entity1.entity2"); 

這應該給你回只是ENTITY1對象,與ENTITY2財產已經初始化。

如果這不起作用,那麼請嘗試更換內部連接的SQL與where子句,即

select {entity1.*} from Entity1Table entity1, Entity2Table entity2 WHERE entity1.fk = entity2.id "); 

這句法然後等同於休眠文檔中給出的示例。

+0

更改連接語法不起作用。從select子句中刪除entity2的列只會導致Hibernate拋出「找不到列」錯誤。 – David 2010-06-25 13:03:59

+0

感謝您的嘗試。我感到困惑 - 據我所見,它應該與冬眠文本中的原生SQL示例一樣,也會獲取帶有「dog」屬性的「cat」。 – mdma 2010-06-25 17:43:10

+0

注意!有些數據庫默認使用交叉連接(示例postgresql)CROSS JOIN子句在兩個或多個表中生成行的笛卡爾積。使用「,」與INNER JOIN – 2017-02-02 08:27:39

0

看看this可以幫你......

+0

不同。令人討厭。但是,這是可行的,是的。 – David 2010-06-25 13:05:07

0

的一種方法是使用θ-風格聯接:

權限被映射到用戶類的集合。

0

我想你想要的是一個獲取連接。這是一個連接,它將數據庫中的列轉換爲對象,但只將這些對象添加到會話緩存中,而不是返回到結果中。

通過JPA,遺留Hibernate API,遺留標準API等,可以做到這一點。

如果您使用的是本地SQL,你應該能夠通過調用SQLQuery::addFetch做到這一點,與更換您的來電addJoin

qry.addFetch("entity2", "entity1", "fk"); 

或類似的東西。我必須承認,我不太明白這些參數應該是什麼意思,並且我無法通過一些快速搜索找到任何好的文檔。

+0

'addFetch'自從Hibernate 3.6以來。問題在於Hibernate 3.5.2。 – xmedeko 2014-03-12 14:48:52

+0

@xmedeko:你說的對,很好。我看不出有什麼辦法在Hibernate 3.5的'SQLQuery'上進行純粹的讀取連接。 – 2014-03-13 18:05:18

+0

這不起作用。 'addFetch'是'addJoin'的一個更加可定製的變體(但基本相同),因爲它返回'FetchReturn'而不是'void'。不幸的是,'FetchReturn'不包含關閉顯式返回連接的選項。 – r0estir0bbe 2014-07-21 07:59:46

1

此處實體1(子)包含實體2(父)的外鍵,實體1(子)類的pojo中應該有一個父類型變量。 我們這是「E」現在查詢將是:

Select ent1.* from Entity1 ent1 inner join ent1.E.id 

這裏ID是ENTITY2