记录一次hibernate3.1 方言问题

错误: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很快找到了关键点。

记录一次hibernate3.1 方言问题_第1张图片

 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> weighted = new HashMap();
    private Map 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 方言问题_第2张图片

切记,hibernate3.1的方言,数据类型的转换,一定是这个:

this.registerColumnType(Types.CLOB,StandardBasicTypes.STRING.getName());

如果需要把达梦其他数据类型转换为string,如果你不知道那个数据类型的int值,可以跟代码去查看,在类:

org.hibernate.loader.custom.CustomLoader 的方法autoDiscoverTypes中加上断点,查看对应的解决方案就可以了。

至此困扰我多次的这个方言问题解决了。

你可能感兴趣的:(oracle,数据库)