Ответ 1
Я думаю, что нашел ответ сам. Если кто-то найдет этот вопрос, вот мой ответ.
Как Spring управляет сессиями Hibernate?
По умолчанию Spring Boot применяет управление транзакциями на уровне хранилища. В этом случае при вызове метода JpaRepository
(или вообще любого метода Repository
) Spring будет:
- Попросите
SessionFactory
создать новую сессию - Откройте эту сессию
- Открыть транзакцию
- Выполните вызванный метод
Repository
- Закрыть транзакцию
- Закройте сессию
Однако если вы примените @Transactional
к классу или методу сервиса, Spring откроет сеанс и транзакцию при входе в метод сервиса, а метод репозитория будет выполнен в рамках существующей транзакции.
Каковы последствия?
Как программист...
- Вам вообще не нужно заниматься транзакциями или сеансами.
- если вы хотите полагаться на функциональность кэширования Hibernate, вы должны указать
@Transactional
в большем объеме, чем хранилище. Кэширование работает только в пределах одной и той жеHibernateSession
. - вы должны решить эквивалентность ваших объектов
@Entity
по их значению Hibernate ID, а не с помощью оператора Java==
. - вам нужно позаботиться о том, чтобы ленивые коллекции (например, в ссылке
@OneToMany
) в ваших классах@Entity
(см.FetchMode.LAZY
в отличие отFetchMode.EAGER
) использовались исключительно в@Transactional
-annotated
Также для справки была бы полезна следующая ссылка: несколько транзакций в одном сеансе
Как и во многих других аспектах Spring, здесь многое можно получить, если вы готовы пожертвовать прямым контролем над своим приложением.