已解决Hibernate错误:hibernate.dialect未设置导致DialectResolutionInfo为null的异常

当未设置’hibernate.dialect’时,无法将DialectResolutionInfo访问为null的HibernateException解决方案

我按照Hibernate官方文档创建了一个使用4.3.5.Final版本的基本Hibernate应用程序。当我执行该应用程序时,尽管所有配置看起来都正确,但我却收到了hibernate.HibernateException: 当'hibernate.dialect'未设置时,无法访问DialectResolutionInfo的错误信息。

解决这个问题花了我很长时间,结果发现是SessionFactory实例创建方式的问题。我用下面的方法创建SessionFactory实例的辅助类。

package com.Olivia.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class SessionFactoryUtil {

	private static SessionFactory sessionFactory;
	
	private static SessionFactory buildSessionFactory() {
        try {
            // 从hibernate.cfg.xml创建SessionFactory
        	SessionFactory sessionFactory = new Configuration().configure("hibernate.cfg.xml")
        				.buildSessionFactory(new StandardServiceRegistryBuilder().build());
        	
            return sessionFactory;
        }
        catch (Throwable ex) {
            // 确保记录异常,因为它可能被吞没
            System.err.println("初始SessionFactory创建失败." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
	
	public static SessionFactory getSessionFactory() {
		if(sessionFactory == null) sessionFactory = buildSessionFactory();
        return sessionFactory;
    }
}

而且我得到了以下的堆栈跟踪:

五月 07, 2014 7:11:59 下午 org.hibernate.cfg.Configuration getConfigurationInputStream
信息: HHH000040: 配置资源: hibernate.cfg.xml
五月 07, 2014 7:12:00 下午 org.hibernate.cfg.Configuration addResource
信息: HHH000221: 从资源读取映射: employee.hbm.xml
五月 07, 2014 7:12:00 下午 org.hibernate.cfg.Configuration doConfigure
信息: HHH000041: 已配置SessionFactory: null
五月 07, 2014 7:12:00 下午 org.hibernate.engine.jdbc.connections.internal.ConnectionProviderInitiator initiateService
警告: HHH000181: 没有遇到合适的连接提供程序,假设应用程序将提供连接
初始SessionFactory创建失败.org.hibernate.HibernateException: 当'hibernate.dialect'未设置时,无法将DialectResolutionInfo访问为null
线程"main"中的异常 java.lang.NullPointerException
	at com.Olivia.hibernate.main.HibernateMain.main(HibernateMain.java:38)

从日志中可以明确看出,Configuration类能够找到hibernate配置文件,并且已经定义了hibernate.dialect,所以异常没有任何意义。

修复HibernateException:当未设置’hibernate.dialect’时无法访问DialectResolutionInfo

经过一些研究和调试,我成功修复了它。官方文档中缺失的部分是我们需要将配置属性应用于StandardServiceRegistryBuilder。当我把实用类更改如下,一切都顺利运行。

package com.Olivia.hibernate.util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class SessionFactoryUtil {

	private static SessionFactory sessionFactory;
	
	private static SessionFactory buildSessionFactory() {
        try {
            // 从hibernate.cfg.xml创建SessionFactory
        	Configuration configuration = new Configuration();
        	configuration.configure("hibernate.cfg.xml");
        	System.out.println("Hibernate配置已加载");
        	
        	//将配置属性设置应用到StandardServiceRegistryBuilder
        	ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        	System.out.println("Hibernate serviceRegistry已创建");
        	
        	SessionFactory sessionFactory = configuration
        				.buildSessionFactory(serviceRegistry);
        	
            return sessionFactory;
        }
        catch (Throwable ex) {
            // 确保记录异常,因为它可能被吞没
            System.err.println("初始SessionFactory创建失败." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }
	
	public static SessionFactory getSessionFactory() {
		if(sessionFactory == null) sessionFactory = buildSessionFactory();
        return sessionFactory;
    }
}

注意StandardServiceRegistryBuilder().applySettings的调用,其中传递了配置属性。Hibernate仍在不断发展,每个版本都带来了许多变化,我觉得文档部分滞后了。希望这能帮助某人解决问题,而不是浪费很多时间进行调试。

bannerAds