Является ли 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.
Особенности этого изменения можно посмотреть по адресу:
- Исходный код: https://github.com/hibernate/hibernate-core/commit/0b10334e403cf2b11ee60725cc5619eaafecc00b
- Билет: https://hibernate.onjira.com/browse/HHH-5991
Некоторые дополнительные ссылки:
Или же
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 a
SessionFactoryImpl` тоже.
Вывод
Эти два метода начальной загрузки влияют на поведение Hibernate. При использовании собственного начального загрузчика Hibernate ведет себя в устаревшем режиме, предшествующем JPA.
При начальной загрузке с использованием JPA Hibernate будет вести себя в соответствии со спецификацией JPA.
Между этими двумя режимами есть несколько различий:
- Как работает режим AUTO flush в отношении собственных SQL-запросов
- Как построен прокси-объект. Традиционно Hibernate не попадал в БД при создании прокси, но JPA требует бросить
EntityNotFoundException
, поэтому требует проверки БД. - можете ли вы удалить неуправляемый объект
Для получения дополнительных сведений об этих различиях ознакомьтесь с
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 и выше, ваш код должен быть:
Конфигурация конфигурации = новая конфигурация (). Configure ();
StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder (). ApplySettings (configuration.getProperties ());
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;