2009-01-21 118 views
3

JPA/Hibernate查詢中允許的連接數是否有限制?JPA/Hibernate最大連接數?

由於休眠doesn't automatically join,我必須明確指定我的JPA/Hibernate查詢中的連接。例如,人有地址,地址有狀態。下面的查詢與地址和狀態滿載檢索人:

select p, a, s from person p left join p.address a left join a.state s where ... 

正如我一直添加連接,我最終(後左12-13連接)達到一個極限,其中休眠產生無效的SQL:

Caused by: java.sql.SQLException: Column 'something69_2_' not found. 

我有Hibernate的方言設置爲我的數據庫實現,MySQL的:

<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> 

是否有數量上的限制聯接Hibernate可以在一個單一的查詢處理?

編輯1:以下是日誌文件:

could not read column value from result set: something69_2_; Column 'something69_2_' not found. 

然而,something69_2_不會出現在SQL查詢。這就像Hibernate生成一個SQL查詢,並期望something69_2_在結果中,而不是。

編輯2:記錄爲一個unfixed Hibernate bug HHH-3035

編輯3類似的問題:這是一個記錄Hibernate bug HHH-3636,其已被固定,但不是任何版本的一部分尚未。

編輯4:我構建了hibernate-core 3.3.2-SNAPSHOT,其中包括錯誤修復HHH-3636,它沒有解決這個問題。

編輯5:錯誤行爲似乎是由ManyToMany或OneToMany關係上的多個LEFT JOIN FETCH觸發的。一個會工作,兩個或三個結果的錯誤。

編輯6:這裏的堆棧跟蹤:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: could not execute query 
     at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:629) 
     at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:73) 
Caused by: org.hibernate.exception.SQLGrammarException: could not execute query 
     at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67) 
     at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) 
     at org.hibernate.loader.Loader.doList(Loader.java:2214) 
     at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2095) 
     at org.hibernate.loader.Loader.list(Loader.java:2090) 
     at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:388) 
     at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338) 
     at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172) 
     at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121) 
     at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79) 
     at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:64) 
     ... 69 more 
Caused by: java.sql.SQLException: Column 'something69_2_' not found. 
     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055) 
     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) 
     at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926) 
     at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1136) 
     at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2777) 
     at org.hibernate.type.IntegerType.get(IntegerType.java:28) 
     at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:113) 
     at org.hibernate.type.NullableType.nullSafeGet(NullableType.java:102) 
     at org.hibernate.loader.Loader.getKeyFromResultSet(Loader.java:1088) 
     at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:553) 
     at org.hibernate.loader.Loader.doQuery(Loader.java:689) 
     at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224) 
     at org.hibernate.loader.Loader.doList(Loader.java:2211) 
     ... 77 more 

編輯7:之所以要這些連接是爲了避免休眠做N + 1個查詢,看Hibernate FAQ on How can I avoid n+1 SQL SELECT queries when running a Hibernate query?

+0

只是好奇,怎麼複雜的是在你的JPA查詢的WHERE子句? – 2009-03-16 04:37:11

+0

Where子句無關緊要。我試過1)沒有where子句,2)簡單where子句(WHERE id = 1)。 – 2009-03-16 16:37:35

+0

爲什麼不使用子查詢獲取而不是加入呢? – toolkit 2009-03-16 17:46:43

回答

2

問題是你爲什麼要首先做這樣一個複雜的查詢?

你有沒有考慮過不同的方法?有關improving performance的文檔提供了一些建議。

1

有Hibernate代碼中沒有限制連接數的內容。這可能是方言中的一個錯誤,或者是數據庫引擎的限制。但是我的錢和一個與連接數無關的bug!您是否曾嘗試在交互式查詢會話中直接運行SQL?

+0

SQL查詢工作得很好。問題是Hibernate試圖讀取一個不存在的結果字段。 – 2009-01-23 00:40:56

1

我一度創出使用Hibernate的MySQL 5.0 61表限制:

ERROR 1116 (HY000): Too many tables; MySQL can only use 61 tables in a join
0

您是否嘗試過與實際使用中的JDBC驅動程序來執行?這可能是jdbc驅動程序的問題。

雖然從列的名稱來看,它正在尋找,我猜想有一些修剪/建設的名稱出錯。絕對看起來更像是一個超出預期限制的錯誤。

0

你是別名全部你的內部聯接嗎?並使用這些別名?我已經看到了Hibernate的一些非常奇怪的現象,當你嘗試使用隱式混疊SELECT從句中做這樣的東西(非常簡單的例子):

select p.address.state from person p 

但是,如果你明確聲明所有的別名,它工作得很好。就像這樣:

select s from person p join p.address a join a.state s 

...甚至這樣的:

select s from person p join p.address.state s