本来是mssql+hibernate+native SQL 应用的很和谐
但是到了把mssql换成mysql,就出了错(同样的数据结构和数据)。
查询方法是:
错误信息:
看到最后Caused by: java.sql.SQLException:
所以我试试用JDBC连接
可以很正常的运行。
后来仔细又看了一下hibernate的执行错误
Caused by: java.sql.SQLException: Column 'id' not found.
是ID 找不到 不是XXX_ID 找不到。这意思貌似hibernate就没按别名alias 来取值
跟踪了一下hibernate
其中在Customer里发现的这一段
hibernate是按照select id,name from tab来解释
而不是 select id XXX_ID , name from tab
这里跟到的数据果然是Hibernate把alias给忽略了。。。
-------------------------------------
继续跟踪hibernate代码.根据调用栈,单步跟踪很快找到
org.hibernate.loader.custom.CustomLoader$ScalarResultColumnProcessor 里面的
这里就是拼装将来要根据列名get出来的结果的地方
alias = metadata.getColumnName( position )
getColumnName 跟进去就是JDBC的实现.
跟踪可以看到.从这里get出来的alias不是真正的aliasName,而是originalColumnName原始列名.
后来试着修改了hibernate各种方言的设置:MySQLDialect,MySQL5Dialect,MySQL5InnoDBDialect等等还是不行。
我用JDBC试了下
mysql-connector-java-5.1.9-bin.jar
mysql-connector-java-5.1.10-bin.jar
mysql-connector-java-5.1.11-bin.jar
三个实现,结果都是一样的.
mysql的JDBC要获取alias只能用getColumnLable,不能用getColumnName
而Hibernate取字段名称的时候就只用 getColumnName.
解决办法有两个,一个是改hibernate,再不就得改mysql.
怕Hibernate对别的数据库实现有影响
所以就拿mysql的JDBC驱动开刀了.
把com.mysql.jdbc.ResultSetMetaData
中的
修改为:
然后把JDBC重新打包一下
再运行就OK了.