Hibernate原生SQL多表查詢欄位名重複問題
Hibernate原生SQL查詢多表關聯,SQL語句要注意的問題
@for&ever 2009-9-4
系統環境:
MySQL5.1
Hibernate3.3
有如下的假定:
實體類 Question 和 Answer分別對應資料表 question 和answer。
並且表 question 和answer 的欄位大部分都一樣,欄位數目也一樣。
執行如下的操作:
1>
使用hibernate 使用原生SQL查詢,
Query q = session.createSQLQuery(sql).addEntity(Question.class).addEntity(Answer.class);
createSQLQuery執行的sql是如下的語句:
select b.*, a.* from question b left join answer a on a.id = b.ansId
在如上的addEntity 實體Question 和 Answer之後,查詢可以進行,但是bean的注值錯誤。
具體現象為,question和answer兩個實體查詢出來後,資料混亂。
這個現象在Hibernate的官方文件中Native SQL Query一章有描述和具體的解決辦法。
2>
於是按著 Hibernate 文件,修改SQL語句如下:
select {b.*}, {a.*} from question {b} left join answer {a} on {a}.id = {b}.ansId
執行查詢後,報錯:
Hibernate: select {b.*}, {a.*} from question {b} left join answer {a} on {a}.id = {b}.ansId
2009-09-04 20:03:53,625 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 1064, SQLState: 42000>
2009-09-04 20:03:53,625 ERROR [org.hibernate.util.JDBCExceptionReporter] - <You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right
syntax to use near ' from question left join answer on .id = .ansId' at line 1>
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.loader.Loader.doList(Loader.java:2231)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2125)
3>
接著修改SQL語句為:
select {bbbb}.*, {aaaa}.* from question {bbbb} left join answer {aaaa} on {aaaa}.id={bbbb}.ansId
查詢,報錯如下:
2009-09-04 19:14:59,140 INFO [org.hibernate.type.IntegerType] - <could not read column value from result set: id10_0_; Column 'id10_0_' not found.>
2009-09-04 19:14:59,140 WARN [org.hibernate.util.JDBCExceptionReporter] - <SQL Error: 0, SQLState: S0022>
2009-09-04 19:14:59,140 ERROR [org.hibernate.util.JDBCExceptionReporter] - <Column 'id10_0_' not found.>
Exception in thread "main" org.hibernate.exception.SQLGrammarException: could not execute query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
4>
最終修改為:
select {bbbb.*}, {aaaa.*} from question {bbbb} left join answer {aaaa} on {aaaa}.id={bbbb}.ansId
查詢結果正常。
總結:
1、使用Hibernate 原生SQL查詢,當多個表的關聯時,或者返回多個表的欄位時,最好要新增別名,並注意新增的別名的寫法;
2、別名alias 的命名不要太短,如上面的例子, a --> aaaa , b --> bbbb ,查詢就一切正常;
3、當多個表格關聯使用原生SQL查詢時,記得對每個要返回的實體 addEntity。