【问题标题】:Is the buildSessionFactory() Configuration method deprecated in Hibernate?在 Hibernate 中是否不推荐使用 buildSessionFactory() 配置方法?
【发布时间】:2012-01-27 03:48:48
【问题描述】:

当我将 Hibernate 版本从 3.6.8 更新到 4.0.0 时,我在此行中收到有关已弃用方法 buildSessionFactory() 的警告:

private static final SessionFactory sessionFactory =
         new Configuration().configure().buildSessionFactory();

Javadoc 建议使用另一种方法

buildSessionFactory(ServiceRegistry serviceRegistry)

但在 documentation 中我发现了已弃用的变体

【问题讨论】:

  • 即使在 4.3.8 快速入门指南中,他们也在使用这个示例: new Configuration() .configure().buildSessionFactory(); :(
  • @VenkataRaju 可能是,这还不错,因为在 Hibernate 5 中一切都变回了,这个例子是正确的,但是(!)这里所有的配置例子都是not valid for Hibernate 5

标签: java hibernate configuration deprecated bootstrapping


【解决方案1】:

是的,它已被弃用。将 SessionFactory 替换为以下内容:

休眠 4.0、4.1、4.2

private static SessionFactory sessionFactory;
private static ServiceRegistry serviceRegistry;

public static SessionFactory createSessionFactory() {
    Configuration configuration = new Configuration();
    configuration.configure();
    ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
            configuration.getProperties()). buildServiceRegistry();
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    return sessionFactory;
}

更新:

Hibernate 4.3 中,ServiceRegistryBuilder 已弃用。请改用以下内容。

serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
            configuration.getProperties()).build();

【讨论】:

  • org.hibernate.service.ServiceRegistryBuilder 也被弃用了!
  • 是的,似乎 ServiceRegistryBuilder 本身已被弃用,查看文档,他们建议改用 StandardServiceRegistryBuilder。所以我想现在应该调用 new StandardRegistryBuilder().applySettings(configuration.getProperties()).build();
  • 我在休眠 4.3 中找不到 StandardRegistryBuilder 会不会是那里改了?
  • 需要 buildServiceRegistry() 而不是 build(),对吗?我找不到 ServiceRegistry.build()。
  • Hibernate 团队的使命似乎是弃用他们创造的一切。
【解决方案2】:

是的,它已被弃用。 http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/cfg/Configuration.html#buildSessionFactory() 专门告诉您使用您找到的其他方法 (buildSessionFactory(ServiceRegistry serviceRegistry)) - 所以使用它。

文档从一个版本复制到另一个版本,并且可能还没有更新(他们不会在每个版本中重写手册) - 所以请相信 Javadocs。

可以在以下位置查看此更改的详细信息:

一些额外的参考资料:

【讨论】:

  • 那么我们现在如何进行会话呢?分配给 serviceRegistry 接口的对象是什么??
  • @IsmailMarmoush - 我还没有玩太多,但添加了一些额外的参考。
【解决方案3】:

public class Hbutil {

    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;
    }

    public static SessionFactory getSessionFactory() {
        return configureSessionFactory();

    }
}

【讨论】:

  • 此代码中使用了一些已弃用的方法。
【解决方案4】:

经过验证的代码可在 Hibernate 4.3.0 中运行。请注意,您可以删除 XML 文件名参数,或者在那里提供您自己的路径。这与此处的其他帖子类似(但错别字已更正),但这是正确的。

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


Configuration configuration = new Configuration();
configuration.configure("/com/rtw/test/hiber/hibernate.cfg.xml");
ServiceRegistry  serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();        
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);

【讨论】:

    【解决方案5】:

    就这么简单:JBoss 文档并非 100% 完美维护。和what the JavaDoc says一起去:buildSessionFactory(ServiceRegistry serviceRegistry)

    【讨论】:

      【解决方案6】:

      在最新的休眠版本 4.3.0 以后创建 SessionFactory 对象的更好方法如下:

      Configuration configuration = new Configuration().configure();
      StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().
      applySettings(configuration.getProperties());
      SessionFactory factory = configuration.buildSessionFactory(builder.build());
      

      【讨论】:

      • 出现错误:Configuration 类型中的方法 buildSessionFactory() 不适用于参数(StandardServiceRegistry)
      【解决方案7】:

      在不同版本的文档之间发现差异并不罕见。大多数开发人员将文档视为一件苦差事,他们往往会拖延。

      根据经验,如果 javadoc 说了一件事情,而一些非 javadoc 文档与之相矛盾,那么 javadoc 很可能更准确。程序员更有可能通过更改代码使 javadoc 保持最新……因为 javadoc 的“源”与代码位于同一文件中。

      @deprecated 标签的情况下,几乎可以肯定javadoc 更准确。开发人员在仔细考虑后弃用某些东西......并且(一般来说)他们不会取消弃用它们。

      【讨论】:

      • ...他们不会反对他们。 ...除非它被称为System.getenv(String)bugs.sun.com/bugdatabase/view_bug.do?bug_id=4199068
      • 经常会发现一些垃圾项目,他们懒惰的开发人员不会费心将文档与代码保持一致,这样他们就会把用户逼疯,而这些项目则试图弄清楚这些该死的垃圾是如何产生的通过翻找本身并希望有比 /** TODO: comment-me */ 更多的东西来工作:-\
      • @bestsss ...或者叫Configuration.buildSessionFactory() ;)
      【解决方案8】:

      如果您使用的是 Hibernate 5.2 及更高版本,则可以使用:

        private static StandardServiceRegistry registry;
        private static SessionFactory sessionFactory;
      
        public static SessionFactory getSessionFactory() {
          if (sessionFactory == null) {
            try {
              // Creating a registry
              registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
      
              // Create the MetadataSources
              MetadataSources sources = new MetadataSources(registry);
      
              // Create the Metadata
              Metadata metadata = sources.getMetadataBuilder().build();
      
              // Create SessionFactory
              sessionFactory = metadata.getSessionFactoryBuilder().build();
      
            } catch (Exception e) {
              e.printStackTrace();
              if (registry != null) {
                StandardServiceRegistryBuilder.destroy(registry);
              }
            }
          }
          return sessionFactory;
        }
      
        //To shut down
       public static void shutdown() {
          if (registry != null) {
            StandardServiceRegistryBuilder.destroy(registry);
          }
        }
      

      【讨论】:

        【解决方案9】:

        TL;DR

        是的,是的。有更好的方法来引导 Hibernate,如下所示。

        Hibernate-native 引导

        旧的 Configuration 对象不如使用自 Hibernate 4 引入的 BootstrapServiceRegistryBuilder 强大:

        final BootstrapServiceRegistryBuilder bsrb = new BootstrapServiceRegistryBuilder()
            .enableAutoClose();
        
        Integrator integrator = integrator();
        if (integrator != null) {
            bsrb.applyIntegrator( integrator );
        }
        
        final BootstrapServiceRegistry bsr = bsrb.build();
        
        final StandardServiceRegistry serviceRegistry = 
            new StandardServiceRegistryBuilder(bsr)
                .applySettings(properties())
                .build();
        
        final MetadataSources metadataSources = new MetadataSources(serviceRegistry);
        
        for (Class annotatedClass : entities()) {
            metadataSources.addAnnotatedClass(annotatedClass);
        }
        
        String[] packages = packages();
        if (packages != null) {
            for (String annotatedPackage : packages) {
                metadataSources.addPackage(annotatedPackage);
            }
        }
        
        String[] resources = resources();
        if (resources != null) {
            for (String resource : resources) {
                metadataSources.addResource(resource);
            }
        }
        
        final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder()
            .enableNewIdentifierGeneratorSupport(true)
            .applyImplicitNamingStrategy(ImplicitNamingStrategyLegacyJpaImpl.INSTANCE);
        
        final List<Type> additionalTypes = additionalTypes();
        if (additionalTypes != null) {
            additionalTypes.stream().forEach(type -> {
                metadataBuilder.applyTypes((typeContributions, sr) -> {
                    if(type instanceof BasicType) {
                        typeContributions.contributeType((BasicType) type);
                    } else if (type instanceof UserType ){
                        typeContributions.contributeType((UserType) type);
                    } else if (type instanceof CompositeUserType) {
                        typeContributions.contributeType((CompositeUserType) type);
                    }
                });
            });
        }
        
        additionalMetadata(metadataBuilder);
        
        MetadataImplementor metadata = (MetadataImplementor) metadataBuilder.build();
        
        final SessionFactoryBuilder sfb = metadata.getSessionFactoryBuilder();
        Interceptor interceptor = interceptor();
        if(interceptor != null) {
            sfb.applyInterceptor(interceptor);
        }
        
        SessionFactory sessionFactory = sfb.build();
        

        JPA 引导

        您还可以使用 JPA 引导 Hibernate:

        PersistenceUnitInfo persistenceUnitInfo = persistenceUnitInfo(getClass().getSimpleName());
        Map configuration = properties();
        
        Interceptor interceptor = interceptor();
        if (interceptor != null) {
            configuration.put(AvailableSettings.INTERCEPTOR, interceptor);
        }
        
        Integrator integrator = integrator();
        if (integrator != null) {
            configuration.put(
                "hibernate.integrator_provider", 
                (IntegratorProvider) () -> Collections.singletonList(integrator));
        }
        
        EntityManagerFactoryBuilderImpl entityManagerFactoryBuilder = 
            new EntityManagerFactoryBuilderImpl(
                new PersistenceUnitInfoDescriptor(persistenceUnitInfo), 
                configuration
        );
        EntityManagerFactory entityManagerFactory = entityManagerFactoryBuilder.build();
        

        这样,您将构建 EntityManagerFactory 而不是 SessionFactory。但是,SessionFactory 也扩展了 EntityManagerFactory, so the actual object that's built is aSessionFactoryImpl`。

        结论

        这两种引导方法会影响 Hibernate 行为。使用本机引导程序时,Hibernate 以旧模式运行,该模式早于 JPA。

        当使用 JPA 引导时,Hibernate 将按照 JPA 规范运行。

        这两种模式有几个区别:

        有关这些差异的更多详细信息,请查看JpaCompliance 类。

        【讨论】:

          【解决方案10】:
          public class HibernateSessionFactory {
          
          private static final SessionFactory sessionFactory = buildSessionFactory1();
          
          private static SessionFactory buildSessionFactory1() {
          Configuration configuration = new Configuration().configure(); // configuration
                                                                          // settings
                                                                          // from
                                                                          // hibernate.cfg.xml
          
          StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
          
          
          serviceRegistryBuilder.applySettings(configuration.getProperties());
          
          ServiceRegistry serviceRegistry = serviceRegistryBuilder.build();
          
          return configuration.buildSessionFactory(serviceRegistry);
          }
          
          public static SessionFactory getSessionFactory() {
          return sessionFactory;
           }
          
          public static void shutdown() {
          // Close caches and connection pools
          getSessionFactory().close();
           }
          

          【讨论】:

          • 'StandardServiceRegistryBuilder' 也已被弃用。
          • @NitinRam StandardServiceRegistryBuilder 未被弃用。
          • 很奇怪,在 Hibernate 中,事情是如何开始和结束弃用的。它曾经在某一时刻。 stackoverflow.com/questions/17911308/…
          【解决方案11】:

          如果有人在更新到 5.1 后会出现这种情况

          StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
                          MetadataSources sources = new MetadataSources(registry);
                          Metadata metadata = sources.getMetadataBuilder().build();
                          sessionFactory = metadata.getSessionFactoryBuilder().build();
          

          而不是 hibernate 4.3 中的以下内容

           ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
                      configuration.getProperties()). buildServiceRegistry();
              sessionFactory = configuration.buildSessionFactory(serviceRegistry);
          

          【讨论】:

            【解决方案12】:

            public void sampleConnection() 抛出异常 {

                 Configuration cfg = new Configuration().addResource("hibernate.cfg.xml").configure();
                 StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());
                 SessionFactory sessionFactory = configuration.buildSessionFactory(ssrb.build());
                 Session session = sessionFactory.openSession();
                 logger.debug(" connection with the database created successfuly.");
            }
            

            【讨论】:

              【解决方案13】:

              我编辑了batbaatar above 创建的方法,所以它接受配置对象作为参数:

                  public static SessionFactory createSessionFactory(Configuration configuration) {
                      serviceRegistry = new StandardServiceRegistryBuilder().applySettings(
                              configuration.getProperties()).build();
                      factory = configuration.buildSessionFactory(serviceRegistry);
                      return factory;
                  }
              

              在我做的主要课程中:

                  private static SessionFactory factory;
                  private static Configuration configuration 
                  ...      
                  configuration = new Configuration();
                  configuration.configure().addAnnotatedClass(Employee.class);
                  // Other configurations, then           
                  factory = createSessionFactory(configuration);
              

              【讨论】:

                【解决方案14】:

                休眠 4.2.2

                import org.hibernate.Session;
                import org.hibernate.SessionFactory;
                import org.hibernate.Transaction;
                import org.hibernate.cfg.Configuration;
                import org.hibernate.service.ServiceRegistry;
                import org.hibernate.service.ServiceRegistryBuilder;
                
                public class Test {
                    public static void main(String[] args) throws Exception
                {
                    Configuration configuration = new Configuration()
                            .configure();
                
                    ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
                            configuration.getProperties()).buildServiceRegistry();
                
                    SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
                
                    Session session = sessionFactory.openSession();
                
                    Transaction transaction = session.beginTransaction();
                
                    Users users = new Users();
                
                    ... ...
                
                    session.save(users);
                
                    transaction.commit();
                
                    session.close();
                
                    sessionFactory.close();
                
                    }
                }
                

                【讨论】:

                  【解决方案15】:
                  Tested on 4.2.7 release
                  
                  package com.national.software.hibernate;
                  
                  import org.hibernate.Session;
                  import org.hibernate.SessionFactory;
                  import org.hibernate.cfg.Configuration;
                  import org.hibernate.service.ServiceRegistry;
                  import org.hibernate.service.ServiceRegistryBuilder;
                  
                  import com.national.software.dto.UserDetails;
                  
                  public class HibernateTest {
                  
                      static SessionFactory sessionFactory;
                  
                      public static void main(String[] args) {
                          // TODO Auto-generated method stub
                  
                          UserDetails user = new UserDetails();
                          user.setUserId(1);
                          user.setUserName("user1");
                  
                          Configuration config = new Configuration();
                          config.configure();
                  
                          ServiceRegistry  serviceRegistry = (ServiceRegistry) new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
                          sessionFactory = config.buildSessionFactory(serviceRegistry);
                  
                          Session session = sessionFactory.openSession();
                          session.beginTransaction();
                          session.save(user);
                          session.getTransaction().commit();
                  
                      }
                  
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    这里有许多在 hibernate 核心框架中被弃用的 API。

                    我们创建了如下的会话工厂:

                    SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();

                    方法 buildSessionFactory 从 hibernate 4 版本中被弃用,它被新的 API 取代。如果您使用的是 hibernate 4.3.0 及更高版本,您的代码必须是:

                    1. 配置配置 = new Configuration().configure();

                    2. StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties());

                    3. SessionFactory 工厂 = configuration.buildSessionFactory(builder.build());

                    类 ServiceRegistryBuilder 从 4.3.0 被 StandardServiceRegistryBuilder 取代。看起来 5.0 版本会有很多变化。对于已弃用的 API 和合适的替代方案,仍然没有太多的明确性。每个增量版本都会出现更多不推荐使用的 API,它们正在微调 5.0 版本的核心框架。

                    【讨论】:

                      【解决方案17】:

                      hibernate 5.3.1,你可以试试这个:

                      ServiceRegistry standardRegistry = 
                                      new StandardServiceRegistryBuilder().configure().build();
                      
                      Metadata sources = new MetadataSources(standardRegistry).addAnnotatedClass(MyEntity.class).getMetadataBuilder().build();
                      
                      SessionFactory sf = sources.buildSessionFactory();
                      

                      【讨论】:

                        【解决方案18】:

                        只需导入以下包,

                        import org.hibernate.cfg.Configuration;
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2015-02-26
                          • 1970-01-01
                          • 2017-05-03
                          • 2020-11-18
                          • 2017-06-19
                          • 2015-04-30
                          • 1970-01-01
                          相关资源
                          最近更新 更多