`
Kevin12
  • 浏览: 231129 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

No Dialect mapping for JDBC type:?类型的错误

阅读更多
当在hibernate中运用原始的sql语句进行操作的的时候,常常会报错,错误很多都是关于
No Dialect mapping for JDBC type:?这里的问号是不同的数字如:-1,1,-9,3等等,每种数字代表一种类型。经过分析和查找,问题常常发生在几个地方
1、错误的配置了hibernate的方言
2、就是你的数据库中的字段和java里面的类型不匹配的问题
错误如下:
org.hibernate.MappingException: No Dialect mapping for JDBC type: -1
Error message:
org.hibernate.MappingException: No Dialect mapping for JDBC type: -1
at org.hibernate.dialect.TypeNames.get(TypeNames.java:56)
at org.hibernate.dialect.TypeNames.get(TypeNames.java:81)
at org.hibernate.dialect.Dialect.getHibernateTypeName(Dialect.java:370)
at org.hibernate.loader.custom.CustomLoader$Metadata.getHibernateType(CustomLoader.java:559)
at org.hibernate.loader.custom.CustomLoader$ScalarResultColumnProcessor.performDiscovery(CustomLoader.java:485)
at org.hibernate.loader.custom.CustomLoader.autoDiscoverTypes(CustomLoader.java:501)
at org.hibernate.loader.Loader.getResultSet(Loader.java:1796)
at org.hibernate.loader.Loader.doQuery(Loader.java:674)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
at org.hibernate.loader.Loader.doList(Loader.java:2220)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
at org.hibernate.loader.Loader.list(Loader.java:2099)
at org.hibernate.loader.custom.CustomLoader.list(CustomLoader.java:289)
at org.hibernate.impl.SessionImpl.listCustomQuery(SessionImpl.java:1695)
at org.hibernate.impl.AbstractSessionImpl.list(AbstractSessionImpl.java:142)
at org.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:152)
at com.tilsi.solr.dao.summary.EntryDAO.queryByEntryId(EntryDAO.java:164)
at com.tilsi.solr.service.db.DbSearchThread.searchSummary(DbSearchThread.java:69)
at com.tilsi.solr.service.db.DbSearchThread.call(DbSearchThread.java:48)
at com.tilsi.solr.service.db.DbSearchThread.call(DbSearchThread.java:1)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

解决方法为:通过查询hibernate的源码,找到问题的根本所在,就是hibernate中不支持对应的数据类型,具体数据类型的值,请查看下表
查看 java.sql.Types 类,可以找到对应类型,调整相应的数据库里的类型,或者其他支持这个类型的方言。
public final static int BIT   =  -7;
public final static int TINYINT  =  -6;
public final static int SMALLINT =   5;
public final static int INTEGER  =   4;
public final static int BIGINT   =  -5;
public final static int FLOAT   =   6;
public final static int REAL   =   7;
public final static int DOUBLE   =   8;
public final static int NUMERIC  =   2;
public final static int DECIMAL  =   3;
public final static int CHAR  =   1;
public final static int VARCHAR  =  12;
public final static int LONGVARCHAR  =  -1;
public final static int DATE   =  91;
public final static int TIME   =  92;
public final static int TIMESTAMP  =  93;
public final static int BINARY  =  -2;
public final static int VARBINARY  =  -3;
public final static int LONGVARBINARY  =  -4;
public final static int NULL  =   0;
public final static int OTHER  = 1111;
public final static int JAVA_OBJECT         = 2000;
public final static int DISTINCT            = 2001;
public final static int STRUCT              = 2002;
public final static int ARRAY               = 2003;
public final static int BLOB                = 2004;
public final static int CLOB                = 2005;
public final static int REF                 = 2006;
public final static int DATALINK = 70;
public final static int BOOLEAN = 16;
public final static int ROWID = -8;
public static final int NCHAR = -15;
public static final int NVARCHAR = -9;
public static final int LONGNVARCHAR = -16;
public static final int NCLOB = 2011;
public static final int SQLXML = 2009;

这类错误,最后的问号表示不确定的数字,但是解决的方法都一样。
首先,自定义一个方言类——Hibernate Dialect,该类需要继承与我们使用的数据库相应的方言类。比如:如果我们用的是MySql(版本为5.x.x),我们需要继承“org.hibernate.dialect.MySQL5Dialect”;如果我们使用的是DB2,那么我们应该继承“org.hibernate.dialect.DB2Dialect”;我用的是SqlServer2008,所以我要继承“org.hibernate.dialect.SQLServerDialect”,参考代码如下:

    import java.sql.Types;  
     
    import org.hibernate.Hibernate;  
    import org.hibernate.dialect.SQLServerDialect;  
     
    public class SqlServer2008Dialect extends SQLServerDialect {  
     
        public SqlServer2008Dialect() {  
            super();  
            registerHibernateType(Types.CHAR, Hibernate.STRING.getName());  
            registerHibernateType(Types.NVARCHAR, Hibernate.STRING.getName());  
            registerHibernateType(Types.LONGNVARCHAR, Hibernate.STRING.getName());  
            registerHibernateType(Types.DECIMAL, Hibernate.DOUBLE.getName());  
        }  
    } 
总之大家可以在“org.hibernate.dialect”这个package中找到与数据库相对应的方言类。在其中,我们需要注意三点:

a、在默认构造方法中继承父类构造方法,同时调用“registerHibernateType(int code, String name)”方法将数据库中该数据类型映射到相应的java类型。code表示数据库中的数据类型整数表示,可以在“java.sql.Types”类中查到相应的数据库类型。name表示我们要映射的java类型。可以从“org.hibernate.Hibernate”中查到。

b、Types类。在Types中定义了数据库常用的字段类型,如:

    ……  
    public final static int LONGVARCHAR =  -1;  
    public final static int TIMESTAMP =  93;  
    …… 
也就是上面我列出的java.sql.Types。
我们可以根据“No Dialect mapping for JDBC type : ”后面紧跟的数字在该类(Types)中找到相应的类型。我们也可以根据数据表中字段的类型找到相应的值。这个值就是registerHibernateType(int code, String name)的第一个参数。

c、Hibernate类。Hibernate中定义了转换的目的类型,如第一段代码所示。能够转化成什么类型,可以在该类中查找。通过调用“getName()”方法得到一个String型。当然,如果你记住了,我们还可以这样写

    import org.hibernate.dialect.SQLServerDialect;  
     
    public class SqlServer2008Dialect extends SQLServerDialect {  
     
        public SqlServer2008Dialect() {  
            super();  
            registerHibernateType(1, "string");  
            registerHibernateType(-9, "string");  
            registerHibernateType(-16, "string");  
            registerHibernateType(3, "double");  
        }  
    } 
其实和上面是一样的,只是把上面所代表的值直接写出来了。需要注意的是super()方法的调用,不调用该方法是否会出现错误,这个我就不知道了,我没有测试,所以最好调一下。
然后,我们还需要在配置文件中作修改,我将连接数据库的方法放在了spring配置文件中了,这段代码就写在applicationContext.xml里面了:
<property name="hibernateProperties">
<props>
<!-- <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect </prop> -->
<prop key="hibernate.dialect">com.sense.workflow.util.SqlServer2008Dialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <!-- 显示sql格式 -->
                <prop key="hibernate.format_sql">false</prop>
</props>
</property>

最后还有一个解决方法:如果你的数据库表中某个字段不可以不用text类型的,将其改成其他类型(如:varchar等)也可以,这个方法虽然简单,当数据库字段必须用text类型的时候该方法就不行了。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics