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。