Ответ
Да, SessionFactory в Hibernate — это тяжеловесный (heavyweight), потокобезопасный объект, который создается один раз на всё приложение. Его «тяжесть» обусловлена сложной и ресурсоемкой инициализацией.
Причины:
- Singleton на уровне приложения: Создается при старте и используется всеми потоками.
- Затратная инициализация: В процессе построения выполняются:
- Чтение и парсинг конфигурации (
hibernate.cfg.xmlили аннотации). - Построение и валидация метамодели всех сущностей (ORM-маппинг).
- Создание и наполнение кешей второго уровня и кеша запросов (если включены).
- Генерация и подготовка SQL-запросов для основных операций.
- Чтение и парсинг конфигурации (
Пример создания (устаревший, но наглядный API):
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
// Этот вызов выполняет всю тяжелую работу
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Best practice: Создавайте SessionFactory единожды при запуске приложения (например, в ServletContextListener или с помощью LocalSessionFactoryBean в Spring) и используйте dependency injection для его переиспользования. Обязательно закрывайте (sessionFactory.close()) при остановке приложения для освобождения ресурсов.
Ответ 18+ 🔞
А, слушай, вот эта твоя SessionFactory в Hibernate — это ж, блядь, не какая-нибудь легковесная хуйня, которую можно на каждый чих создавать. Это, сука, монстр, здоровенный такой объект, который на всё приложение один. Потокобезопасный, да, но создаётся он так, будто ты, блядь, целый завод запускаешь.
Почему он такой тяжёлый, ёпта?
- Один на всех, как отец родной: Создаёшь при старте — и потом все потоки к нему, как к кормушке, ломятся.
- Инициализация — просто пиздец: Пока он построится, он столько дел переделает, мать его:
- Конфигурацию твою прочитает, распарсит, осмыслит.
- Всю метамодель сущностей построит и проверит, не накосячил ли ты в маппингах.
- Кеши второго уровня и запросов, если ты их включил, начнёт готовить.
- Даже базовые SQL-запросы заранее сгенерирует, чтобы потом не ебаться.
Вот, смотри, как его раньше создавали (старый способ, но суть ясна):
Configuration configuration = new Configuration().configure();
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
// А вот этот вызов — это и есть тот самый момент, когда всё ебётся и грузится
SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
Как с этим жить, чтобы не обосраться? Создай эту фабрику ОДИН РАЗ, блядь, когда приложение стартует (в ServletContextListener или через LocalSessionFactoryBean в Spring, если ты с ним). А потом просто таскай её за собой, куда надо, через dependency injection. И главное — не забудь её прибить (sessionFactory.close()), когда приложение кончается, а то ресурсы повиснут, как сопли.