今天做了個用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代碼
- 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());
- }
- }
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代碼
- ……
- public final static int LONGVARCHAR = -1;
- public final static int TIMESTAMP = 93;
- ……
……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代碼
- 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");
- }
- }
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代碼
- <?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>
<?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;
}
注意紅色的部分。