因为某个Java软件在不同的项目上要连接不同厂家的数据库,所以使用的hibernate。之前在各个项目上都用的挺好的,连接过sqlserver,oracle,mysql,国产达梦数据库等。
直至最近,某个项目要求使用国产人大金仓数据库,查了官方文档后,引入相关jar包,更改好hibernate配置文件。一运行,结果报这个错。然后就开始了曲折的解决bug的路程。
首先,根据报错能判断到是程序里实体类的数据类型跟数据库对应列的数据类型不一致,数据库是char(),实体类里使用的是String,在网上查到,需要在map文件里加上type="char"..按文件里说的加上。是不报错了。 结果,在执行查询的时候,又开始报另一个错“java.lang.String cannot be cast to java.lang.Character”。
查看报错堆栈,打断点,进入hibernate的jar包内部,发现是之前报错的字段的值作为查询条件传给数据库时报的错。
然后又是各种搜索,chatgpt都用上了,查到了各种办法,有更改map文件type类型的,有重写方言包的,一一试过之后,发现都不管用。
然后,偶然间,在查看hibernate配置文件时,发现一条没注意过的配置,之前也没写过这条配置,应该是从人大金仓官方样例中拷贝过来的:
<property name="hbm2ddl.auto">validate</property>
好奇心驱使下,查了它的意义,原来是验证hibernate配置信息与数据库中的表同步的设置。然后想到之前断点进入方言包的时候,看到人大金仓的方言包里已经对char()类型做了转换,所以就算不验证,应该也是可以用的,验证的话,反而通不过,因为string确实是对应varchar类型,跟char()类型是不对应的。于是我打算将验证关掉试试。将那条配置改为如下:
<property name="hbm2ddl.auto">none</property>
然后,去掉之前在map文件里添加的type="char"配置。
然后,大功告成。
此次bug还是由于对hibernate了解不全面,以至于解决的路程比较曲折,花了我一晚上时间。希望能对遇到同样问题的同仁们有所帮助。