错误:com.sun.proxy.$Proxy553 cannot be cast to java.lang.string
我们项目上,将mysql数据库迁移到达梦数据库,这样会造成数据库类型上在java查询下,会有不兼容的问题,比如clob,text等,可能都有问题,这就需要用方言去解决了。
之前text就出现了报错,找了半天也没能解决,后来改成了varchar(8000),虽然 改了不报错了,感觉可能会有隐患,只是项目上要的紧,只好先这样了。
今天有个功能用到了colb,仍然报错,虽然错误的输出不一样,但是错误的根源是一样的,就是数据库字段和对应的hibernate解释的字段不匹配。
据我分析,我需要将数据库对应的字段,映射到hibernate的string上,就可以展示了,可是问题来了,在网上找了很多,都是用这种去写的:
registerHibernateType(Types.DATE, Hibernate.TIMESTAMP.getName());//自定义数据类型
也行别的版本,这样写可能会成功,但是我用的hibernate3.1 根本不可以。
仍然会报错。
第一天就这样过去了,第二天就痛定思痛,只是找网上的资料不知道什么时候才能解决,我最后决定跟着源码走,思路很清晰,就是要找到映射这一块,看看为啥没有映射成功。
eclipse无法在jar包里面加断点,一上午渡过去,仍然没有找到具体位置。
下午的时候,决定用idea,虽然时间过去不少了,但是工欲善其事必先利其器,用idea可以在jar里面加断点去看源码,所以使用idea很快找到了关键点。
protected void autoDiscoverTypes(ResultSet rs) {try {Metadata metadata = new Metadata(this.getFactory(), rs);List aliases = new ArrayList();List types = new ArrayList();this.rowProcessor.prepareForAutoDiscovery(metadata);for(int i = 0; i < this.rowProcessor.columnProcessors.length; ++i) {this.rowProcessor.columnProcessors[i].performDiscovery(metadata, types, aliases);}this.resultTypes = ArrayHelper.toTypeArray(types);this.transformerAliases = ArrayHelper.toStringArray(aliases);} catch (SQLException var6) {throw new HibernateException("Exception while trying to autodiscover types.", var6);}}
这个关键点找到了,在【performDiscovery】方法中,就是做映射的,为啥不成功,进去一看便知:
public class TypeNames {private Map<Integer, Map<Integer, String>> weighted = new HashMap();private Map<Integer, String> defaults = new HashMap();public TypeNames() {}public String get(int typecode) throws MappingException {String result = (String)this.defaults.get(typecode);if (result == null) {throw new MappingException("No Dialect mapping for JDBC type: " + typecode);} else {return result;}}
关键的方法就是在这里,TypeNames.get(),这个方法,获取方言配置类里面的映射,是取的TypeNames.default这个Map里面的数据,到这里问题就基本明确了。
切记,hibernate3.1的方言,数据类型的转换,一定是这个:
this.registerColumnType(Types.CLOB,StandardBasicTypes.STRING.getName());
如果需要把达梦其他数据类型转换为string,如果你不知道那个数据类型的int值,可以跟代码去查看,在类:
org.hibernate.loader.custom.CustomLoader 的方法autoDiscoverTypes中加上断点,查看对应的解决方案就可以了。
至此困扰我多次的这个方言问题解决了。