关于Hibernate的Dialect

org.hibernate HibernateException Dialect must be explicitly set :*** 
使用Hibernate,有时候会遇到类似上面的异常。 
使用代码获取Session是要使用Configuration要调用Configure方法。这个方法很容易被遗忘。
 
SessionFactory sf=config.configure().buildSessionFactory(); Session session=sf.openSession(); 

通过API可以知道configure()方法的作用如下:

Use the mappings and properties specified in an application resource named hibernate.cfg.xml
configure()方法默认加载hibernate.cfg.xml文件,使该文件的映射和配置在应用程序中使用;configure()还有重载的方法来指定配置分别是
 configure(Document document)
 configure(File configFile)
 configure(String resource)
 configure(URL url) 

  

若使用configure方法那么就可以在hibernate.cfg.xml中配置数据库的dialect:
      
<property name="dialect">数据库对应的dialect</property>

 

通过配置来指定数据库对于的的dialect,具体的数据库和数据库对于的dialect如下:
 
 
RDBMSDialect
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
 
 
使用spring和hibernate时如果使用时,有时候会去掉hibernate.cfg.xml,那么则要在Spring中配置dialect
<property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
                <prop key="hibernate.format_sql">true</prop>
                <!-- 配置hibernate.dialect-->
              <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                 <prop key="hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory</prop> 
            </props>
</property>

  

 
 
通过Hibernate Reference 可以知道,Dialect这部分内容使和数据库的移植性有相关的,在3.2之前的版本,Hibernate是要求用户明确指定数据库的Dialect的,3.2或以上版本通过java.sql.DataBaseMetaData来确定数据库;不过该文档同时指出来这种方法局限于Hibernate已知的数据库且无法进行配置和覆盖。3.3以后,用户可以通过重写org.hibernate.resolver.DialectResolver的resolveDialect方法来自定义方言,“要注册一个或多个解析者,只要用 'hibernate.dialect_resolvers' 配置设置指定它们(由逗号、制表符或空格隔开)就可以了(请参考 org.hibernate.cfg.Environment DIALECT_RESOLVERS)”。
用户定义的类通过AvailableSettings.DIALECT_RESOLVERS 获取类名,然后通过反射来注册DialectResolver。AvailableSettings.DIALECT_RESOLVERS 配置的类在determineResolvers链上先于StandardDialectResolver,所以自定义的解释者更优先处理DatabaseMetaData。
以下使hibernate初始化DialectResolver链的类。
import org.hibernate.HibernateException;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.service.classloading.spi.ClassLoaderService;
import org.hibernate.service.spi.ServiceException;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.jdbc.dialect.spi.DialectResolver;
import org.hibernate.service.spi.BasicServiceInitiator;
 
/**
* Standard initiator for the standard {@link DialectResolver} service
*
* @author Steve Ebersole
*/
public class DialectResolverInitiator implements BasicServiceInitiator<DialectResolver> {
    public static final DialectResolverInitiator INSTANCE = new DialectResolverInitiator();
 
    @Override
    public Class<DialectResolver> getServiceInitiated() {
        return DialectResolver.class;
    }
 
    @Override
    public DialectResolver initiateService(Map configurationValues, ServiceRegistryImplementor registry) {
        return new DialectResolverSet( determineResolvers( configurationValues, registry ) );
    }
 
    private List<DialectResolver> determineResolvers(Map configurationValues, ServiceRegistryImplementor registry) {
        final List<DialectResolver> resolvers = new ArrayList
();
 
        final String resolverImplNames = (String) configurationValues.get( AvailableSettings.DIALECT_RESOLVERS );
 
        if ( StringHelper.isNotEmpty( resolverImplNames ) ) {
            final ClassLoaderService classLoaderService = registry.getService( ClassLoaderService.class );
            for ( String resolverImplName : StringHelper.split( ", \n\r\f\t", resolverImplNames ) ) {
                try {
                    resolvers.add( (DialectResolver) classLoaderService.classForName( resolverImplName ).newInstance() );
                }
                catch (HibernateException e) {
                    throw e;
                }
                catch (Exception e) {
                    throw new ServiceException( "Unable to instantiate named dialect resolver [" + resolverImplName + "]", e );
                }
            }
        }
 
        resolvers.add( new StandardDialectResolver() );
        return resolvers;
    }
}
 

 

 
 
posted @ 2013-12-06 14:38  Be a programer  阅读(967)  评论(0编辑  收藏  举报