關於No Dialect mapping for JDBC type :-9 hibernate執行原生sql語句問題

來源:互聯網
上載者:User

今天做了個用hibernate直接執行原生sql的查詢,報錯No Dialect mapping for JDBC type :-9

 

在網上查了一下。有很多解決方案,這裡總結一下。方便大家尋找。

 

第一種: No Dialect mapping for JDBC type: 3;

  查看文章    
ERROR 解決記錄 - No Dialect mapping for JDBC type: 3;2007-11-28 16:34
        今天在使用getSession().createSQLQuery("SELECT SUM(aloneIp) FROM table").list();
時出現了錯誤:No Dialect mapping for JDBC type: 3;

baidu,google了一番後,各位都說:“出現這個原因是說伺服器端的資料類型並不能和Java的BigDecimal資料類型成功映射。”;

不過我的資料庫中“aloneIp”列的類型為INTEGER,出現這個錯誤不知是何原因。

根據以下解決方案,問題得以解決,記錄之:
1、建立一個MMySQLDialect extends org.hibernate.dialect.MySQLDialect (我使用的資料庫是MYSQL)並在裡面補充註冊新的類型映射。如下:import java.sql.Types;
import org.hibernate.Hibernate;
import org.hibernate.dialect.MySQLDialect;

public class MMySQLDialect extends MySQLDialect {
    public MMySQLDialect () {
        super();
        registerHibernateType(Types.DECIMAL, Hibernate.BIG_INTEGER.getName());
    }
}

2、把Hibernate裡的Dialect改成我們第一步建立的新的Dialect

<prop key="hibernate.dialect">[包路徑].MMySQLDialect </prop>

第二種: org.hibernate.MappingException: No Dialect mapping for JDBC type: -1

環境是:SQL Server2005 + Hibernate3.2.5

問題原因:

資料庫表中有text類型的欄位,而Hibernate在native查詢中沒有註冊這個欄位,因此發生這個錯誤。

解決方案:

寫一個類、修改hibernate設定檔。 寫一個Dialect的子類,這裡我 extends SQLServerDialectt類:

package com.zy.util;

import java.sql.Types;

import org.hibernate.Hibernate;
import org.hibernate.dialect.SQLServerDialect;

public class DialectForInkfish extends SQLServerDialect {
public DialectForInkfish() {
   super();
   //registerHibernateType(Types.LONGVARCHAR, 65535, "text");//.LONGVARCHAR
   registerHibernateType(Types.DECIMAL, Hibernate.BIG_DECIMAL.getName());  
        registerHibernateType(-1, Hibernate.STRING.getName());
}

}

修改Hibernate設定檔hibernate.cfg.xml,把

<property name="dialect">  
   org.hibernate.dialect.SQLServerDialect
</property>

修改成:

<property name="dialect">  
   com.zy.util.DialectForInkfish
</property>

 

說明: 如果你的資料庫是mysql,而又用了decimal類型,報錯應該是 No Dialect mapping for JDBC type: 3 . 注意這個3, 它說明hibernate不能將這種資料類型映射到你的java類中. 就需要在自訂的方言中用到:

registerHibernateType(Types.DECIMAL, Hibernate.BIG_DECIMAL.getName());  

 

 

一個比較詳細的說明:

前段時間碰到了這類錯誤,最後的問號表示不確定的數字,但是解決的方法都一樣。

 

首先,自訂一個方言類——Hibernate Dialect,該類需要繼承與我們使用的資料庫相應的方言類。比如:如果我們用的是MySql(版本為5.x.x),我們需要繼承“org.hibernate.dialect.MySQL5Dialect”;如果我們使用的是DB2,那麼我們應該繼承“org.hibernate.dialect.DB2Dialect”;我用的是SqlServer2008,所以我要繼承“org.hibernate.dialect.SQLServerDialect”,參考代碼如下:

Java代碼
  1. import java.sql.Types;   
  2.   
  3. import org.hibernate.Hibernate;   
  4. import org.hibernate.dialect.SQLServerDialect;   
  5.   
  6. public class SqlServer2008Dialect extends SQLServerDialect {   
  7.   
  8.     public SqlServer2008Dialect() {   
  9.         super();   
  10.         registerHibernateType(Types.CHAR, Hibernate.STRING.getName());   
  11.         registerHibernateType(Types.NVARCHAR, Hibernate.STRING.getName());   
  12.         registerHibernateType(Types.LONGNVARCHAR, Hibernate.STRING.getName());   
  13.         registerHibernateType(Types.DECIMAL, Hibernate.DOUBLE.getName());   
  14.     }   
  15. }  
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中定義了資料庫常用的欄位類型,如:

Java代碼
  1. ……   
  2. public final static int LONGVARCHAR =  -1;   
  3. public final static int TIMESTAMP =  93;   
  4. ……  
……public final static int LONGVARCHAR =  -1;public final static int TIMESTAMP =  93;……

 

我們可以根據“No Dialect mapping for JDBC type : ”後面緊跟的數字在該類(Types)中找到相應的類型。我們也可以根據資料表中欄位的類型找到相應的值。這個值就是registerHibernateType(int code, String name)的第一個參數。

c、Hibernate類。Hibernate中定義了轉換的目的類型,如第一段代碼所示。能夠轉化成什麼類型,可以在該類中尋找。通過調用“getName()”方法得到一個String型。當然,如果你記住了,我們還可以這樣寫

Java代碼
  1. import org.hibernate.dialect.SQLServerDialect;   
  2.   
  3. public class SqlServer2008Dialect extends SQLServerDialect {   
  4.   
  5.     public SqlServer2008Dialect() {   
  6.         super();   
  7.         registerHibernateType(1, "string");   
  8.         registerHibernateType(-9, "string");   
  9.         registerHibernateType(-16, "string");   
  10.         registerHibernateType(3, "double");   
  11.     }   
  12. }  
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");}}

 

其實和上面是一樣的,只是把上面所代表的值直接寫出來了。O(∩_∩)O哈哈~。需要注意的是super()方法的調用,不調用該方法是否會出現錯誤,我這就不知道了,這個我沒有做過測試,所以最好調一下。

 

 

然後,我們還需要在設定檔中作修改。我用的是EJB3,所以我在META-INF檔案夾下的persistent.xml檔案中添加屬性“hibernate.dialect”,value值為“xxx.xxx.SqlServer2008Dialect ”,xxx表示包名,這個大家都知道。代碼如下:

Java代碼
  1. <?xml version="1.0" encoding="UTF-8" ?>   
  2. <persistence xmlns="http://java.sun.com/xml/ns/persistence"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence   
  5.         http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"   
  6.     version="1.0">   
  7.     <persistence-unit name="DateSource">   
  8.         <jta-data-source>java:/SqlServerDS</jta-data-source>   
  9.         <properties>   
  10.             <property name="hibernate.dialect" value="xxx.xxx.SqlServer2008Dialect"/>   
  11.             <property name="hibernate.hbm2ddl.auto" value="none" />   
  12.         </properties>   
  13.     </persistence-unit>   
  14. </persistence>  
<?xml version="1.0" encoding="UTF-8" ?><persistence xmlns="http://java.sun.com/xml/ns/persistence"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/persistence        http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"version="1.0"><persistence-unit name="DateSource"><jta-data-source>java:/SqlServerDS</jta-data-source><properties><property name="hibernate.dialect" value="xxx.xxx.SqlServer2008Dialect"/><property name="hibernate.hbm2ddl.auto" value="none" /></properties></persistence-unit></persistence>

 打包部署,OK!當然,如果你使用的是Hibernate,則修改Hibernate設定檔hibernate.cfg.xml,將“hibernate.dialect”屬性的值改為自己的方言類“xxx.xxx.SqlServer2008Dialect ”即可。

 

而我自己遇到的是報錯9 :

但是我沒用上面的方法。

我只是規定傳回值的類型就可以了。

public List topCataList(int catalevel){
     Session session = getSession();
     List list = new ArrayList();
     String sql = "select TUSHU_DAIMA from Magazine_Cata where CATA_LEVEL = :level";
     try {
  Query query = session.createSQLQuery(sql).addScalar("TUSHU_DAIMA", Hibernate.STRING);
  query.setInteger("level", catalevel);
  list = query.list();
     } catch (HibernateException e) {
  e.printStackTrace();
     }
    
     return list;
    
 }

注意紅色的部分。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.