Специфікація JPA у Spring, доступна в пакеті org.springframework.orm.jpa, містить комплексні засоби підтримки Java Persistence API аналогічно інтеграції з Hibernate, водночас враховуючи базову реалізацію для надання додаткових функцій.

Три варіанти налаштування JPA в оточенні Spring

Підтримка JPA в Spring передбачає три способи налаштування EntityManagerFactory з JPA, яка використовується додатком для отримання диспетчера сутностей.

  • Використання LocalEntityManagerFactoryBean

  • Отримання EntityManagerFactory з JNDI

  • Використання LocalContainerEntityManagerFactoryBean

Використання LocalEntityManagerFactoryBean

Цей варіант можна використовувати лише у простих оточеннях розгортання, таких як автономні програми та інтеграційні тести.

LocalEntityManagerFactoryBean створює фабрику EntityManagerFactory, придатну для простих оточень розгортання, де програма використовує лише JPA для доступу до даних. Бін-фабрика використовує механізм автоматичного визначення PersistenceProvider з JPA (відповідно до початкового завантаження JPA в Java SE) і в більшості випадків вимагає зазначити лише ім'я одиниці збереження. У наступному прикладі на XML налаштований такий бін:


<beans>
    <bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="myPersistenceUnit"/>
    </bean>
</beans>

Ця форма розгортання JPA є найпростішою і обмеженою. Посилатися на існуюче визначення біна DataSource з JDBC не можна, а підтримка глобальних транзакцій відсутня. До того ж, зв'язування (перетворення байт-коду) постійних класів залежить від конкретного постачальника, і часто потрібно встановити конкретного агента JVM при запуску. Ця опція буде достатньою лише для автономних програм та тестових оточень, для яких розроблена специфікація JPA.

Отримання EntityManagerFactory з JNDI

Цей варіант можна використовувати при розгортанні на сервері Java EE. Перевір документацію для свого сервера, щоб дізнатися, як розгорнути кастомний постачальник JPA на твоєму сервері, що дозволить використовувати постачальника, відмінного від постачальника сервера за замовчуванням.

Отримання EntityManagerFactory з JNDI (наприклад, в оточенні Java EE) це питання зміни конфігурації XML, як показано в наступному прикладі:


<beans>
    <jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
</beans>
div>

Ця дія передбачає стандартне початкове завантаження Java EE. Сервер Java EE автоматично виявляє одиниці збереженості (по суті, файли META-INF/persistence.xml у jar-файлах додатків) та записи persistence-unit-ref у дескрипторі розгортання Java EE (наприклад, web.xml) і визначає місце розташування контексту іменування оточення для цих одиниць збереження.

У такому сценарії розгортання одиниць збереження, включно зі зв'язуванням (перетворенням байт-коду) класів постійного зберігання, повністю покладається на сервер Java EE. DataSource з JDBC визначається через розташування JNDI у файлі META-INF/persistence.xml. Транзакції EntityManager є невід'ємною частиною JTA-підсистеми сервера. Spring просто використовує отриману EntityManagerFactory, передаючи її об'єктам програми через впровадження залежностей і керуючи транзакціями для одиниці збереженості (зазвичай через JtaTransactionManager).

Якщо в одному додатку використовується кілька одиниць збереження, імена бінів таких одиниць збереження, що отримуються з JNDI, повинні збігатися з іменами одиниць збереження, які додаток використовує для посилання на них (наприклад, в анотаціях @PersistenceUnit та @PersistenceContext).

Використання LocalContainerEntityManagerFactoryBean

Цей варіант можна обрати для повноцінного використання засобів JPA в оточенні програм на базі Spring. Це передбачає вебконтейнери, такі як Tomcat, автономні програми та інтеграційні тести зі складними вимогами до постійного зберігання.

Якщо необхідно спеціально зконфігурувати налаштування Hibernate, альтернативою може стати налаштування власного LocalSessionFactoryBean з Hibernate замість звичайного LocalContainerEntityManagerFactoryBean з JPA, що дозволить йому взаємодіяти з кодом доступу JPA, а також з нативним кодом доступу Hibernate. Докладніші відомості див. у розділі "Нативне налаштування Hibernate для взаємодії з JPA".

LocalContainerEntityManagerFactoryBean дає повний контроль над конфігурацією EntityManagerFactory і підходить для оточень, в яких потрібно тонке налаштування. LocalContainerEntityManagerFactoryBean створює екземпляр PersistenceUnitInfo на основі файлу persistence.xml, наданої стратегії dataSourceLookup та зазначеного loadTimeWeaver. Таким чином, можна працювати з кастомними джерелами даних поза JNDI і управляти процесом прив'язування. У наступному прикладі показано типове визначення біна для LocalContainerEntityManagerFactoryBean:


<beans>
    <bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="someDataSource"/>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
        </property>
    </bean>
</beans>

У цьому прикладі показано типовий файл persistence.xml:


<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
        <mapping-file>META-INF/orm.xml</mapping-file>
        <exclude-unlisted-classes/>
    </persistence-unit>
</persistence>
Скорочення <exclude-unlisted-classes/> ; вказує, що сканування анотованих класів сутностей не повинно здійснюватися. Очевидне значення "true" (<exclude-unlisted-classes>true</exclude-unlisted-classes/>) також означає відсутність перевірки. <exclude-unlisted-classes>false</exclude-unlisted-classes/> викликає перевірку. Однак рекомендуємо опустити елемент exclude-unlisted-classes, якщо потрібно здійснювати сканування класів сутностей.

Використання LocalContainerEntityManagerFactoryBean є найбільш ефективним варіантом налаштування JPA, що забезпечує гнучку локальну конфігурацію у додатку. Він підтримує посилання на існуючий DataSource з JDBC, підтримує локальні та глобальні транзакції тощо. Однак він також пред'являє вимоги до середовища виконання, такі як наявність завантажувача класів з можливістю прив'язування, якщо постачальнику збереження потрібно перетворення байт-коду. Цей варіант може конфліктувати з вбудованими засобами JPA сервера Java EE. У повнофункціональному оточенні Java EE розглянь можливість отримання EntityManagerFactory з JNDI. Як варіант, встанови кастомне persistenceXmlLocation у визначенні LocalContainerEntityManagerFactoryBean (наприклад, META-INF/my-persistence.xml) і увімкни лише дескриптор із цим ім'ям у jar-файли твоєї програми. Оскільки сервер Java EE шукає лише стандартні файли META-INF/persistence.xml, він ігнорує такі кастомні одиниці збереження, що дозволяє уникнути конфліктів з налаштуванням JPA на основі Spring. (Це стосується, наприклад, до Resin 3.1).

Коли необхідне прив'язування під час завантаження?

Не всі постачальники JPA вимагають наявності агента JVM. Hibernate є саме таким прикладом. Якщо твій постачальник не вимагає наявності агента або у тебе є інші альтернативи, наприклад, можливість застосовувати засоби, що розширюють функціонал, під час складання через кастомний компілятор або встановлення на основі Ant, то не слід використовувати інструмент прив'язування під час завантаження.

Інтерфейс LoadTimeWeaver – це клас, що міститься в Spring, який дозволяє підключати екземпляри ClassTransformer з JPA певним чином, залежно від того, чи є оточення вебконтейнером чи сервером програм. Підключення ClassTransformers через agent зазвичай є неефективним. Агенти працюють всією віртуальною машиною і перевіряють кожен завантажуваний клас, що зазвичай небажано в оточенні виробничих серверів.

Spring містить кілька реалізацій LoadTimeWeaver для різних оточень, що дозволяє застосовувати екземпляри ClassTransformer тільки для кожного завантажувача класів, а не для кожної віртуальної машини.

Детальнішу інформацію про реалізацію LoadTimeWeaver та їх налаштування, як типізованої, так і адаптованої до різних платформам (наприклад, Tomcat, JBoss і WebSphere) див. Spring на чолі з АОП.

Як описано в розділі, присвяченому конфігурації Spring, налаштувати LoadTimeWeaver для всього контексту можна за допомогою анотації @EnableLoadTimeWeaving або XML-елемента context:load-time- weaver. Такий глобальний інструмент прив'язування автоматично підхоплюється всіма екземплярами LocalContainerEntityManagerFactoryBean з JPA. У наступному прикладі показано найкращий спосіб налаштування інструменту прив'язування під час завантаження, що забезпечує автоматичне виявлення платформи (наприклад, завантажувач класів Tomcat з підтримкою прив'язування або агент JVM з Spring) та автоматичне поширення засобу прив'язування на всі біни, що підтримують інструмент прив'язування:


<context:load-time-weaver/>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    ...
</bean>

Однак за необхідності можна вручну встановити виділений інструмент прив'язування через властивість loadTimeWeaver, як показано в наведеному нижче прикладі:


<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
    </property>
</bean>

Незалежно від того, як налаштовано прив'язування під час завантаження (LTW), за допомогою цієї техніки програми JPA, що покладаються на інструментацію, можуть виконуватися на цільовій платформі (наприклад Tomcat) без необхідності використання агента. Це особливо важливо, якщо програми хоста використовують різні реалізації JPA, оскільки перетворювачі JPA застосовуються лише на рівні класу-завантажувача і, таким чином, ізольовані один від одного.

Робота з кількома одиницями збереження

Для додатків, які використовують кілька місць одиниць збереження (зберігаються, наприклад, у різних JAR-файлах в classpath), Spring пропонує PersistenceUnitManager, який діє як центральний репозиторій і дозволяє уникнути процесу виявлення одиниць збереження, що може бути витратним. Реалізація за замовчуванням дає змогу задавати кілька позицій. Ці розташування парсяться і згодом витягуються через ім'я одиниці збереження. (За замовчуванням у classpath виконується пошук файлів META-INF/persistence.xml). У цьому прикладі налаштовано кілька позицій:


<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="persistenceXmlLocations">
        <list>
            <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
            <value>classpath:/my/package/**/custom-persistence.xml</value>
            <value>classpath*:META-INF/persistence.xml</value>
        </list>
    </property>
    <property name="dataSources">
        <map>
            <entry key="localDataSource" value-ref="local-db"/>
            <entry key="remoteDataSource" value-ref="remote-db"/>
        </map>
    </property>
    <!-- якщо джерело даних не вказано, використовуйте цей -->
    <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitManager" ref="pum"/>
    <property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

Реалізація за замовчуванням дозволяє налаштовувати екземпляри PersistenceUnitInfo (до їх передачі постачальнику JPA) або декларативно (через його) властивості, які впливають на всі одиниці, що розміщуються (hosted), або програмно (через PersistenceUnitPostProcessor, який дозволяє проводити вибірку одиниць збереження). Якщо PersistenceUnitManager не встановлено, він буде створений і використаний всередині LocalContainerEntityManagerFactoryBean.

Фонове початкове завантаження

LocalContainerEntityManagerFactoryBean підтримує функцію початкового завантаження фону через властивість bootstrapExecutor, як показано в наступному прикладі:


<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="bootstrapExecutor">
        <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
    </property>
</bean>

Фактичне початкове завантаження постачальника JPA передається вказаному виконавцю, а потім, паралельно, потоку початкового завантаження програми. Відкритий проксі EntityManagerFactory може бути впроваджений в інші компоненти програми і навіть здатний відповідати на перевірку конфігурації EntityManagerFactoryInfo. Однак, якщо до реального постачальника JPA звертаються інші компоненти (наприклад, викликаючи createEntityManager), ці виклики блокуються до завершення початкового завантаження фону. Зокрема, якщо ти використовуєш Spring Data JPA, не забудь налаштувати відкладене початкове завантаження і для його репозиторіїв.

Реалізація DAO на основі JPA: EntityManagerFactory та EntityManager

Хоча екземпляри EntityManagerFactory є потокобезпечними, екземпляри EntityManager такими не є. Впроваджений EntityManager з JPA поводиться як EntityManager, отриманий з оточення JNDI сервера додатків, як визначено специфікацією JPA. Він делегує всі виклики поточному транзакційному EntityManager, якщо такий є. В іншому випадку він повертається до новоствореного EntityManager для кожної операції, фактично роблячи його використання потокобезпечним.

Можна писати код на звичайному JPA без будь-яких залежностей Spring, використовуючи впроваджену EntityManagerFactory або EntityManager. Spring може розпізнавати анотації @PersistenceUnit та @PersistenceContext як на рівні поля, так і на рівні методу, якщо активовано PersistenceAnnotationBeanPostProcessor. У наступному прикладі показано звичайну реалізацію DAO на JPA, яка використовує анотацію @PersistenceUnit:

Java

public class ProductDaoImpl implements ProductDao {
    private EntityManagerFactory emf;
    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }
    public Collection loadProductsByCategory(String category) {
        EntityManager em = this.emf.createEntityManager();
        try {
            Query query = em.createQuery("from Product as p where p.category = ?1");
            query.setParameter(1, category);
            return query.getResultList();
        }
        finally {
            if (em != null) {
                em.close();
            }
        }
    }
}
Kotlin

class ProductDaoImpl : ProductDao {
    private lateinit var emf: EntityManagerFactory
    @PersistenceUnit
    fun setEntityManagerFactory(emf: EntityManagerFactory) {
        this.emf = emf
    }
    fun loadProductsByCategory(category: String): Collection<*> {
        val em = this.emf.createEntityManager()
        val query = em.createQuery("from Product as p where p.category = ?1");
        query.setParameter(1, category);
        return query.resultList;
    }
}

Попередній DAO не залежить від Spring і, як і раніше, добре вписується в контекст програми Spring. Більше того, DAO використовує переваги анотацій, щоб вимагати впровадження стандартної EntityManagerFactory, як показано в наступному прикладі визначення біна:


<beans>
    <!-- постпроцесор бінів для JPA-анотацій -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
    <bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>

В якості альтернативи явному визначенню PersistenceAnnotationBeanPostProcessor, розглянь можливість використання XML-елемента context:annotation -config зі Spring у конфігурації контексту програми. Таким чином, усі стандартні постпроцесори Spring для конфігурації на основі анотацій, включно з CommonAnnotationBeanPostProcessor тощо, автоматично реєструватимуться.

Розглянемо наступний приклад:


<beans>
    <!-- постпроцесори для всіх стандартних анотацій конфігурації -->
    <context:annotation-config/>
    <bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>

Основна проблема з таким DAO полягає в тому, що він завжди створює новий EntityManager через фабрику. Можна уникнути цього, якщо зробити запит на транзакційний EntityManager (також іменованиц "загальним EntityManager", оскільки він є загальним, потокобезпечним проксі для реального транзакційного EntityManager), який буде впроваджений замість фабрики. У цьому прикладі показано, як це зробити:

Java

public class ProductDaoImpl implements ProductDao {
    @PersistenceContext
    private EntityManager em;
    public Collection loadProductsByCategory(String category) {
        Query query = em.createQuery("from Product as p where p.category = :category");
        query.setParameter("category", category);
        return query.getResultList();
    }
}
Kotlin

class ProductDaoImpl : ProductDao {
    @PersistenceContext
    private lateinit var em: EntityManager
    fun loadProductsByCategory(category: String): Collection<*> {
        val query = em.createQuery("from Product as p where p.category = :category")
        query.setParameter("category", category)
        return query.resultList
    }
}

Анотація @PersistenceContext має необов'язковий атрибут type, який за замовчуванням має значення PersistenceContextType.TRANSACTION. Це значення можна використовувати за замовчуванням для загального проксі EntityManager. Альтернатива, а саме PersistenceContextType.EXTENDED, є зовсім іншою справою. В результаті виходить так званий розширений EntityManager, який не є потокобезпечним і, отже, не повинен використовуватися в компоненті, до якого відкритий одночасний доступ, такому як, наприклад, керований Spring бін-одинак. Екземпляри розширеного EntityManager призначені для використання виключно в компонентах, що зберігають стан, які, наприклад, утримуються в сесії, водночас життєвий цикл EntityManager не прив'язаний до поточної транзакції, а повністю залежить від програми.

Впровадження залежностей на рівні методу та поля

Можна застосовувати анотації, що позначають впровадження залежностей (такі як @PersistenceUnit і @PersistenceContext) для полів або методів усередині класу — звідси вирази "впровадження на рівні методу" і "впровадження лише на рівні поля". Анотації лише на рівні полів лаконічні і прості у використанні, тоді як анотації лише на рівні методів дозволяють додатково обробляти впроваджену залежність. В обох випадках видимість члена (публічний, захищений чи приватний) не має значення.

Що щодо анотацій на рівні класів?

На платформі Java EE вони використовуються для оголошення залежностей, а не для впровадження ресурсів.

Впроваджуваний EntityManager управляється за допомогою Spring (враховує поточну транзакцію). Навіть якщо нова реалізація DAO використовує впровадження EntityManager на рівні методів замість EntityManagerFactory, жодних змін у XML контексті програми не потрібне завдяки використанню анотацій.

Головна перевага цього стилю DAO полягає в тому, що він залежить тільки від Java Persistence API. Імпорт будь-якого класу Spring не вимагається. Більш того, оскільки анотації JPA розпізнаються, використання застосовується контейнером Spring автоматично. Це привабливо з точки зору неагресивності і може здаватися більш природним для розробників JPA.

Транзакції JPA, керовані Spring

Рекомендуємо ознайомитися з розділом "Декларативне керування транзакціями", якщо ти ще не зробив цього, щоб отримати більш детальні роз'яснення щодо декларативних транзакцій у Spring.

Рекомендована стратегія для JPA – локальні транзакції за допомогою вбудованої підтримки транзакцій JPA. JpaTransactionManager зі Spring пропонує безліч засобів, відомих за локальними транзакціями з JDBC (такі як специфічні для транзакцій рівні ізоляції та оптимізація режиму "тільки для читання" на рівні ресурсів), щодо будь-якого звичайного пулу з'єднань JDBC (без вимог XA. що зареєстрований JpaDialect підтримує отримання базового Connection з JDBC. Spring містить діалекти для реалізацій EclipseLink та Hibernate через JPA.

Як безпосередня альтернатива, нативний HibernateTransactionManager зі Spring здатен взаємодіяти з кодом доступу JPA, адаптуючись до деяких особливостей Hibernate та забезпечуючи взаємодію з JDBC. Це має особливий сенс у поєднанні з налаштуванням LocalSessionFactoryBean. Докладніше див. у розділі "Нативне налаштування Hibernate для взаємодії з JPA"

Основні відомості про JpaDialect та JpaVendorAdapter

У якості розширеної функції JpaTransactionManager та підкласи AbstractEntityManagerFactoryBean дозволяють передавати користувальницький JpaDialect у властивість біна jpaDialect. Реалізація JpaDialect може включати такі розширені можливості, що підтримуються Spring, зазвичай залежно від виробника:

  • Застосування специфічної семантики транзакцій (наприклад, кастомного рівня ізоляції або часу очікування транзакції)

  • Отримання транзакційного Connection JDBC (щоб відкрити його на DAO-об'єктах на основі JDBC)

  • Розширене перетворення PersistenceExceptions у DataAccessExceptions зі Spring

Це особливо корисно у разі спеціальної семантики транзакцій і для розширеного перетворення винятків. Реалізація за замовчуванням (DefaultJpaDialect) не надає жодних спеціальних можливостей, і якщо потрібні зазначені раніше функції, необхідно вказувати відповідний діалект.

JpaVendorAdapter, будучи ще ширшим засобом адаптації постачальника в першу чергу для повнофункціонального налаштування LocalContainerEntityManagerFactoryBean зі Spring, поєднує можливості JpaDialect з іншими специфічними для постачальника за замовчуванням. Завдання HibernateJpaVendorAdapter або EclipseLinkJpaVendorAdapter є найбільш зручним способом автоматичного налаштування EntityManagerFactory для Hibernate або EclipseLink відповідно. Зверни увагу, що ці адаптери постачальників в першу чергу призначені для використання при керуванні транзакціями на основі Spring (тобто для використання з JpaTransactionManager).

Див. javadoc JpaDialect та JpaVendorAdapter для отримання більш детальної інформації про їхню роботу та про те, як вони використовуються в межах засобів підтримки Spring для JPA.

Налаштування JPA за допомогою управління транзакціями через JTA

Як альтернатива JpaTransactionManager, Spring також дозволяє координувати транзакції з кількома ресурсами через JTA або в оточенні Java EE, або за допомогою окремого координатора транзакцій, такого як Atomikos. Крім вибору JtaTransactionManager замість JpaTransactionManager, необхідно зробити ще кілька кроків:

  • Основні пули з'єднань JDBC повинні бути сумісні з XA та інтегровані з координатором транзакцій. Зазвичай в оточенні Java EE це робиться просто шляхом відкриття DataSource іншого типу через JNDI. Подробиці див. у документації до твого сервера програм. Аналогічно, автономний координатор транзакцій зазвичай поставляється зі спеціалізованими варіантами DataSource, інтегрованими з XA. Знову ж таки, ознайомся з документацією.

  • Налаштування EntityManagerFactory з JPA має бути налаштовано для JTA. Все залежить від виробника, але зазвичай це робиться через спеціальні властивості, які потрібно вказати як jpaProperties для LocalContainerEntityManagerFactoryBean. У разі Hibernate ці властивості навіть залежать від версії. Подробиці див. у документації з Hibernate.

  • HibernateJpaVendorAdapter з Spring застосовує певні Spring-орієнтовані значення за замовчуванням, такі як режим звільнення з'єднання, on-close, який збігається з власним значенням за замовчуванням з Hibernate до Hibernate 5.0, але вже не збігається з ним у Hibernate 5.1+. Для налаштування JTA переконайся, що тип транзакції твоєї одиниці збереження оголошений як "JTA". Як варіант, встанови властивість hibernate.connection.handling_modeз Hibernate 5.2 у DELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENT, щоб відновити власне значення Hibernate за замовчуванням. Відповідні нотатки див. у розділі "Неправдиві попередження сервера програм під час використання Hibernate ".

  • Як альтернативу, розглянь можливість отримання EntityManagerFactory з самого сервера додатків (тобто через JNDI-пошук замість локально оголошеного LocalContainerEntityManagerFactoryBean). Надана сервером EntityManagerFactory може вимагати спеціальних визначень у конфігурації твого сервера (що робить розгортання менш платформонезалежним), але вона налаштована для JTA-оточення сервера.

Нативне налаштування Hibernate та нативні транзакції Hibernate для взаємодії з JPA

Нативне налаштування LocalSessionFactoryBean у поєднанні з HibernateTransactionManager з анотаціями @PersistenceContext та іншим кодом доступу JPA. SessionFactory з Hibernate тепер нативно реалізує інтерфейс EntityManagerFactory з JPA, а дескриптор Session з Hibernate нативно є EntityManager для JPA. Засоби підтримки JPA в Spring автоматично визначають власні сесії Hibernate.

Тому таке нативне налаштування Hibernate може служити заміною стандартній комбінації LocalContainerEntityManagerFactoryBean та JpaTransactionManager із JPA у багатьох сценаріях, дозволяючи взаємодіяти з SessionFactory.getCurrentSession() (а також HibernateTemplate) поряд з анотацією @PersistenceContext EntityManager в межах однієї локальної транзакції. Таке налаштування також забезпечує більш тісну інтеграцію з Hibernate і більшу гнучкість конфігурації, оскільки вона не обмежена контрактами завантажувального шаблону JPA. Hibernate надає ще більше функціональних можливостей (наприклад, кастомне налаштування Hibernate Integrator, інтеграцію контейнера бінів Hibernate 5.3 та суворішу оптимізацію для транзакцій у режимі "тільки для читання"). І останнє, але не по важливості: також можна виразити нативне налаштування Hibernate через LocalSessionFactoryBuilder, з легкістю виконуючи ітерацію конфігурації на основі анотації @Bean (без використання FactoryBean).

LocalSessionFactoryBean та LocalSessionFactoryBuilder підтримують початкове завантаження фону, як і LocalContainerEntityManagerFactoryBean з JPA. Вступну інформацію див. у розділі "Фонове початкове завантаження".

Для LocalSessionFactoryBean це доступно через властивість bootstrapExecutor.У програмному LocalSessionFactoryBuilder перевантажений метод buildSessionFactory приймає аргумент виконавця початкового завантаження.