hibernate実行原生sql文問題


今日はhibernateで生sqlの照会を直接実行しました。No Dialect mapping for JDBC typeを間違えました。
 
インターネットで調べてみました。多くの解決方法があります。ここでまとめてみます。みんなが探しやすいです。
 
第一種類:No Dialect mapping for JDBC type:3;
今日はget Session().createSQLQuery(「SELECT SUM(aloneIp)FROM table」).list()を使っています。
時にエラーが発生しました。No Dialect mapping for JDBC type:3;
baiduは、googleが1回行った後、皆さんは「サーバー側のデータの種類が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、HybernateのDialectを私達の第一歩の新しいDialectに変えます。
< prop key ="hibernate.dialect" > [   ].MMySQLDialect </ prop >
第二種類:org.hibernation.MappingException:No Dialect mapping for JDBC type:-1
環境は:SQL Server 2005+Hibernate 3.2.5
問題の原因:
データベーステーブルにはtextタイプのフィールドがありますが、Hibernateはnativeクエリにこのフィールドを登録していないため、このエラーが発生しました。
解決方法:
クラスを書いて、ヒップホップの設定ファイルを修正します。Dialectのサブクラスを書いて、ここで私はextends SQLServerDialectクラス:
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());
}

}
Hbernameプロファイル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に注意してください。hibernateはこのタイプをあなたのjavaクラスにマッピングできないと説明しています。カスタム方言で使わなければなりません。
registerHibernateType(Types.DECIMAL, Hibernate.BIG_DECIMAL.getName());  
比較的詳細な説明:
この間このようなエラーに遭いました。最後の疑問符は不確定な数字を表しましたが、解決の方法は同じです。
 
まず、私たちが使っているデータベースに対応する方言類を継承する必要がある方言類をカスタマイズします。例えば、私達が使っているのがMySql(バージョンは5.x.x)なら、私達は「org.hibernate.dialect.MySQL 5 Dialect」を受け継ぐ必要があります。私たちがDB 2を使うなら、「org.hibernate.dialect.DB 2 Dialect」を受け継ぐべきです。Sql Server 2008を使っていますので、「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());   
        }   
    }  
 
つまり、「org.hibernate.dialect」というpackageでは、データベースに対応する方言類を見つけることができます。その中で、私達は三つの点に注意しなければなりません。
a、デフォルトの構造方法では、親の構造方法を継承しながら、「register HybernateType(int code,String name)」という方法を呼び出して、データベース内のこのデータタイプを対応するjavaタイプにマッピングする。コードはデータベース中のデータタイプの整数表現を表しています。「java.sql.Types」クラスで該当するデータベースタイプを調べられます。nameは私たちがマッピングするjavaタイプを表しています。「org.hibernate.Hbernate」から調べることができます。
b、Types類。Typeでは、データベースで使用されるフィールドタイプを定義します。
public final static int LONGVARCHAR =  -1;   
public final static int TIMESTAMP =  93;   
私たちは「No Dialect mapping for JDBC type」の後に続く数字によって該当するタイプを見つけることができます。データテーブルのフィールドの種類に応じて、対応する値を見つけられます。この値がregister Hbernature Typeの最初のパラメータです。
c、Hibernate類。Hibernateでは、変換の目的タイプが定義されています。どのタイプに変換できますか?このクラスで検索できます。「get Name()」を呼び出すことで、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");   
        }   
    }  
上と同じです。上の代表の値を直接書いただけです。O(∩∩)Oははは~。注意が必要なのはsuper()方法の呼び出しです。この方法を起動しないとエラーが発生するかどうかは分かりません。これはテストしたことがないので、調整したほうがいいです。
そして、私たちは設定ファイルの中で修正が必要です。私はEJB 3を使っていますので、META-INFフォルダの下のpersistent.xmlファイルに属性「hibernate.dialect」を追加しました。value値は「xxx.xx.Sql Server 2008 Dialect」です。コードは以下の通りです
    <?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!もちろん、Hbernateを使用する場合は、Hbernateプロファイルhibernate.cfg.xmlを修正して、「hibernate.dialect」属性の値を自分の方言類「xx.xxx.Sql Server 2008 Dialect」に変更すればいいです。
自分で会ったのはエラーです。
しかし、上記の方法は使いませんでした。
戻り値の種類だけを規定すればいいです。
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;
    
 }
赤い部分に注意してください。