出处:(hibernate中使用原生的sql语句,报如下错误:)
MySQL No Dialect mapping for JDBC type: -1
代码:
List list = session.createSQLQuery(sql).list();
分析:产生些问题的原因是因表中的某个字段类型在hibernate中找不到对应的类型。而导致的,每一种类型都对应一种type:
类型名称 | 显示长度 | 数据库类型 | JAVA类型 | JDBC类型(int) | Types属性 |
VARCHAR | L+N | VARCHAR | java.lang.String | 12 | Types.VARCHAR |
CHAR | N | CHAR | java.lang.String | 1 | Types.CHAR |
BLOB | L+N | BLOB | java.lang.byte[] | -4 | Types.LONGVARBINARY |
TEXT | 65535 | VARCHAR | java.lang.String | -1 | Types.LONGVARCHAR |
INTEGER | 4 | INTEGER UNSIGNED | java.lang.Long | 4 | Types.INTEGER |
TINYINT | 3 | TINYINT UNSIGNED | java.lang.Integer | -6 | Types.TINYINT |
SMALLINT | 5 | SMALLINT UNSIGNED | java.lang.Integer | 5 | Types.SMALLINT |
MEDIUMINT | 8 | MEDIUMINT UNSIGNED | java.lang.Integer | 4 | Types.INTEGER |
BIT | 1 | BIT | java.lang.Boolean | -7 | Types.BIT |
BIGINT | 20 | BIGINT UNSIGNED | java.math.BigInteger | -5 | Types.BIGINT |
FLOAT | 4+8 | FLOAT | java.lang.Float | 7 | Types.REAL |
DOUBLE | 22 | DOUBLE | java.lang.Double | 8 | Types.DOUBLE |
DECIMAL | 11 | DECIMAL | java.math.BigDecimal | 3 | Types.DECIMAL |
BOOLEAN | 1 | 同TINYINT | java.lang.Integer | -6 | Types.TINYINT |
DATE | 10 | DATE | java.sql.Date | 91 | Types.DATE |
TIME | 8 | TIME | java.sql.Time | 92 | Types.TIME |
DATETIME | 19 | DATETIME | java.sql.Timestamp | 93 | Types.TIMESTAMP |
TIMESTAMP | 19 | TIMESTAMP | java.sql.Timestamp | 93 | Types.TIMESTAMP |
YEAR | 4 | YEAR | java.sql.Date | 91 | Types.DATE |
解决方法:1
更新hibernate方言(因为最新的hibernate言可能提供了对这种类型的支持)以下是言的汇总:
RDBMS | 方言 |
---|---|
DB2 | org.hibernate.dialect.DB2Dialect |
DB2 AS/400 | org.hibernate.dialect.DB2400Dialect |
DB2 OS390 | org.hibernate.dialect.DB2390Dialect |
PostgreSQL | org.hibernate.dialect.PostgreSQLDialect |
MySQL | org.hibernate.dialect.MySQLDialect |
MySQL with InnoDB | org.hibernate.dialect.MySQLInnoDBDialect |
MySQL with MyISAM | org.hibernate.dialect.MySQLMyISAMDialect |
Oracle (any version) | org.hibernate.dialect.OracleDialect |
Oracle 9i/10g | org.hibernate.dialect.Oracle9Dialect |
Sybase | org.hibernate.dialect.SybaseDialect |
Sybase Anywhere | org.hibernate.dialect.SybaseAnywhereDialect |
Microsoft SQL Server | org.hibernate.dialect.SQLServerDialect |
SAP DB | org.hibernate.dialect.SAPDBDialect |
Informix | org.hibernate.dialect.InformixDialect |
HypersonicSQL | org.hibernate.dialect.HSQLDialect |
Ingres | org.hibernate.dialect.IngresDialect |
Progress | org.hibernate.dialect.ProgressDialect |
Mckoi SQL | org.hibernate.dialect.MckoiDialect |
Interbase | org.hibernate.dialect.InterbaseDialect |
Pointbase | org.hibernate.dialect.PointbaseDialect |
FrontBase | org.hibernate.dialect.FrontbaseDialect |
Firebird | org.hibernate.dialect.FirebirdDialect |
以mysql为例:如果以前org.hibernate.dialect.MySQLDialect,那么现在改成:org.hibernate.dialect.MySQLInnoDBDialect
方法2: 如果更新方言还是不行,那可以自己写方言,并配置到hibernate中..
package xm.helper; import java.sql.Types; import org.hibernate.Hibernate; import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.function.StandardSQLFunction; public class XmMySQLDialect extends MySQLDialect { public XmMySQLDialect (){ //把报错的类型注册到hibernate类型的映射中去.... registerHibernateType(-1, Hibernate.STRING.getName()); //也可以把mysql类型注册到,比如hibernate支持longtext registerColumnType(Types.VARCHAR, "longtext"); } }
修改hibernate的配置文件:
<property name="hibernate.dialect">xm.helper.XmMySQLDialect</property>
方法3:
使用原生的jdbc,自己包装,不使用createSQLQuery()方法;
public List<Object[]> exeQuery(final String sql) { final List<Object[]> results = new ArrayList<Object[]>(); sessionFactory.openSession().doWork(new Work() { public void execute(Connection paramConnection) throws SQLException { java.sql.PreparedStatement psta = paramConnection.prepareStatement(sql); ResultSet rs = psta.executeQuery(); int columnCount = rs.getMetaData().getColumnCount(); while(rs.next()){ Object[] rows = new Object[columnCount]; for (int j=0; j<columnCount; ++j) { rows[j] = rs.getObject(j+1); } results.add(rows); }
rs.close();
psta.close();
paramConnection.close(); } }); return results; }