【问题标题】:Configure sessionFactory with Spring, Hibernate and LocalSessionFactoryBuilder使用 Spring、Hibernate 和 LocalSessionFactoryBuilder 配置 sessionFactory
【发布时间】:2013-01-26 05:10:48
【问题描述】:

我正在尝试使用 spring 3.2 和 hibernate 4 创建sessionFactory bean。为此,我使用了以下代码。但问题是buildSessionFactory()弃用,建议在javadoc 中改用buildSessionFactory(ServiceRegistry serviceRegistry)。但是,我无法理解什么是 ServiceRegistry 以及如何使用 buildSessionFactory(ServiceRegistry serviceRegistry)


@Configuration
public class AppConfig {

    ...


    @Bean
    public SessionFactory sessionFactory() {
    return new LocalSessionFactoryBuilder(dataSource())
        .scanPackages("com.mypackages")
        .addProperties(hibernateProperties())
        .buildSessionFactory();

    }
}

【问题讨论】:

    标签: java spring hibernate sessionfactory


    【解决方案1】:

    Artem Shafranov 提供的答案并不完全正确,您可能会像我一样遇到一个非常令人困惑的问题。

    如果你使用

    hibernate.hbm2ddl.auto
    

    您的应用程序将无法启动,因为 hbm2dll 中的连接池将设置为 UserSuppliedConnectionProviderImpl(基本上是一个很好的说法:null)。你会看到这个异常:

    org.hibernate.service.UnknownUnwrapTypeException: Cannot unwrap to requested type [javax.sql.DataSource]
    

    原因与 hbm2dll 使用的 ServiceRegistry 有关,但它与 Spring 不兼容。使用许多建议的编程会话配置方法,在执行 hbm2dll 时它还没有正确的引用。

    对我有用的唯一方法是以下

    @Inject
    DataSource datasource;
    
    @Bean
    @SuppressWarnings("deprecation")
    public SessionFactory sessionFactory() throws IOException{
    
        LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
        sessionFactoryBean.setPackagesToScan("nl.your.model");
        sessionFactoryBean.setHibernateProperties(hibernateProperties());
        sessionFactoryBean.setDataSource(datasource);
        sessionFactoryBean.afterPropertiesSet();
    
        return sessionFactoryBean.getObject();
    }
    

    使用 LocalSessionFactoryBuilder 失败。令人惊讶的是,使用 StandardServiceRegistryBuilder 也失败了。

    真是令人困惑的问题。

    【讨论】:

      【解决方案2】:

      你也可以不使用链接编写代码:

      LocalSessionFactoryBuilder builder = new LocalSessionFactoryBuilder(dataSource());
      builder.scanPackages("com.mypackages");
      builder.addProperties(hibernateProperties());
      return builder.buildSessionFactory();
      

      稍微冗长但不像@SuppressWarnings("deprecation")那么臭

      【讨论】:

        【解决方案3】:

        ServiceRegistry 接口与服务的概念有关(这是 Hibernate 4 的新功能)。服务是为 Hibernate 提供各种功能并且用户可以插入替代实现的类。详情请见this wiki page

        你说得对,在 Hibernate 的 Configuration 类中不推荐使用方法 buildSessionFactory(),而使用方法 buildSessionFactory(ServiceRegistry serviceRegistry)。在纯 Hibernate 的环境中(没有 Spring),假设您将以这样的方式初始化 ServiceRegistry 的实例:

        private static SessionFactory sessionFactory;
        private static ServiceRegistry serviceRegistry;
        
        private static SessionFactory configureSessionFactory() throws HibernateException {
            Configuration configuration = new Configuration();
            configuration.configure();
        
            serviceRegistry = new ServiceRegistryBuilder()
                     .applySettings(configuration.getProperties())
                     .buildServiceRegistry();
        
            sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            return sessionFactory;
        }
        

        但现在已弃用的方法 buildSessionFactory() 也为您执行 ServiceRegistry 的相同初始化。

        Spring 的 LocalSessionFactoryBuilder 类只是 Hibernate 的 Configuration 类的扩展。但是由于 Spring 的所有具体工作都是在覆盖方法 LocalSessionFactoryBuilder.buildSessionFactory() 中完成的,因此您不能在 Spring 的环境中使用方法 buildSessionFactory(ServiceRegistry serviceRegistry)。没什么,因为可以使用 buildSessionFactory() 来完成相同的工作。所以让我们把AppConfig中的方法注解为@SuppressWarnings("deprecation"),耐心等待Spring提供与Hibernate 4更好的集成。

        【讨论】:

        • 这个答案是最新的吗?
        • @dtrunk 如果我没记错的话,即使对于 Spring 4.0.0.RC1,答案仍然是实际的
        猜你喜欢
        • 2015-12-31
        • 1970-01-01
        • 2017-02-10
        • 1970-01-01
        • 2011-12-28
        • 2014-07-28
        • 1970-01-01
        • 2012-11-19
        • 1970-01-01
        相关资源
        最近更新 更多