Является ли buildSessionFactory() устаревшим в hibernate 4?

Когда я обновил версию Hibernate с 3.6.8.final до 4.0.0.final, я получил предупреждение об устаревшем методе buildSessionFactory() в этой строке:

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

Javadoc рекомендует использовать другой метод

buildSessionFactory(ServiceRegistry serviceRegistry)

но в документации я нашел устаревший вариант:(

Можете ли вы помочь мне с этим небольшим недоразумением?

16 ответов

Решение

Да, это не рекомендуется. Замените ваш SessionFactory следующим:

В Hibernate 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();

Да, это устарело. http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/cfg/Configuration.html() специально предлагает вам использовать другой метод, который вы нашли вместо этого (buildSessionFactory(ServiceRegistry serviceRegistry)) - так что пользуйся.

Документация копируется от выпуска к выпуску и, вероятно, просто еще не была обновлена ​​(они не переписывают руководство с каждым выпуском) - так что доверяйте Javadocs.

Особенности этого изменения можно посмотреть по адресу:

Некоторые дополнительные ссылки:

Или же

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();

    }
}

Код проверен для работы в 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);

Это так просто: документы JBoss не на 100% в хорошем состоянии. Идти с тем, что говорит JavaDoc: buildSessionFactory(ServiceRegistry serviceRegistry),

Нередко можно найти несоответствия между разными версиями документации. Большинство разработчиков рассматривают документацию как рутинную работу и склонны откладывать ее.

Как правило, если Javadoc говорит одно, а некоторая документация, не относящаяся к Javadoc, противоречит этому, есть вероятность, что Javadoc является более точным. Программисты с большей вероятностью будут обновлять Javadoc, внося изменения в код... потому что "источник" для Javadoc находится в том же файле, что и код.

В случае @deprecated Теги, это виртуальная уверенность, что Javadoc является более точным. Разработчики осуждают вещи после тщательного рассмотрения... и (вообще говоря) они не обесценивают их.

Лучший способ создания объекта SessionFactory в последнем выпуске hibernate 4.3.0 и последующих версиях заключается в следующем:

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

Если вы используете 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);
    }
  }

TL;DR

Да, это. Есть способы лучше запустить Hibernate, например следующие.

Hibernate-native bootstrap

Наследие Configuration объект менее мощный, чем использование BootstrapServiceRegistryBuilder, представленный с Hibernate 4:

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

Вы также можете запустить Hibernate с помощью JPA:

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 класс.

Если кто здесь после обновления до 5.1 вот как это работает

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

вместо приведенного ниже в спящем режиме 4.3

 ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(
            configuration.getProperties()). buildServiceRegistry();
    sessionFactory = configuration.buildSessionFactory(serviceRegistry);
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();
 }

Здесь много API, которые устарели в структуре ядра hibernate.

мы создали фабрику сессий, как показано ниже:

SessionFactory sessionFactory = новая конфигурация (). Configure (). BuildSessionFactory ();

Метод buildSessionFactory устарел в выпуске hibernate 4 и заменен новым API. Если вы используете Hibernate 4.3.0 и выше, ваш код должен быть:

  1. Конфигурация конфигурации = новая конфигурация (). Configure ();

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

  3. SessionFactory factory = configuration.buildSessionFactory (builder.build ());

Класс ServiceRegistryBuilder заменен StandardServiceRegistryBuilder с 4.3.0. Похоже, в версии 5.0 будет много изменений. Тем не менее, нет особой ясности в отношении устаревших API и подходящих альтернатив для использования. Каждый инкрементный выпуск выпускается с более устаревшим API, они служат для тонкой настройки базовой платформы для выпуска 5.0.

В hibernate 5.3.1, вы можете попробовать это:

ServiceRegistry standardRegistry = 
                new StandardServiceRegistryBuilder().configure().build();

Metadata sources = new MetadataSources(standardRegistry).addAnnotatedClass(MyEntity.class).getMetadataBuilder().build();

SessionFactory sf = sources.buildSessionFactory();

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.");
}

В Hibernate 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();

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

    }

}

Я отредактировал метод, созданный batbaatar выше, чтобы он принимал объект конфигурации в качестве параметра:

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

Просто импортируйте следующий пакет,

import org.hibernate.cfg.Configuration;
Другие вопросы по тегам