Глава 2. Архитектура
Оглавление-
2.1. Обзор
- 2.1.1. Минимальная архитектура
- 2.1.2. Комплексная архитектура
- 2.1.3. Основной API
- 2.2. Контекстные сессии
2.1. Обзор
На приведённой ниже диаграмме представлен высокоуровневый вид архитектуры Hibernate:
К сожалению, мы не можем предоставить подробный обзор всех возможных архитектур времени выполнения. Hibernate достаточно гибкий, чтобы его можно было использовать многими способами во многих, многих архитектурах. Мы, однако, проиллюстрируем 2 конкретные, так как они являются «крайностями».
2.1.1. Минимальная архитектура
«Минимальная» архитектура имеет приложение, управляющее своими собственными JDBC-соединениями и обеспечивающее их подключения к Hibernate; кроме того, приложение управляет транзакциями для себя. Этот подход использует минимальный набор обращений к Hibernate API.
2.1.2. Комплексная архитектура
«Комплексная» архитектура абстрагирует приложение от базового JDBC/JTA API и позволяет Hibernate управлять деталями.
2.1.3. Основной API
Ниже приведено краткое описание некоторых элементов API, изображённых на предыдущих диаграммах (вы увидите их более подробно в последующих главах).
-
SessionFactory (
org.hibernate.SessionFactory
) -
Потокобезопасный, неизменяемый кэш скомпилированных отображений для одной базы данных.
Фабрика для экземпляров
org.hibernate.Session
. Клиентorg.hibernate.connection.ConnectionProvider
. Опционально поддерживает кэш второго уровня данных, которые можно повторно использовать между транзакциями на уровне процесса или кластера. -
Session (
org.hibernate.Session
) -
Однопоточный, недолговечный (short-lived) объект, представляющий собой соглашение между приложением
и постоянным хранилищем. Обёртка JDBC
java.sql.Connection
. Фабрика дляorg.hibernate.Transaction
. Поддерживаеткэш первого уровня
постоянных (persistent) объектов и коллекций приложения; этот кэш используется при навигации по графу объекта или поиска объектов по идентификатору. - Постоянные (persistent) объекты и коллекции
-
Недолговечные (short-lived) однопоточные объекты, содержащие постоянное состояние и бизнес-функционал.
Это могут быть обычные JavaBeans/POJO объекты. Они связаны именно с одним
org.hibernate.Session
. Как толькоorg.hibernate.Session
будет закрыт, они будут отсоединены (detached) и свободны для использования в любом уровне приложения (например, непосредственно как объекты передачи данных в презентацию и из презентации). Глава 11. Работа с объектами обсуждает переходные (transient), постоянные (persistent) и отсоединённые (detached) состояния объектов. - Переходные (transient) и отсоединённые (detached) объекты и коллекции
-
Экземпляры постоянных (persistent) классов, которые в настоящее время не связаны
с
org.hibernate.Session
. Они, возможно, были созданы экземпляром приложения и еще не сохранены, или они, возможно, были созданы экземпляром закрытогоorg.hibernate.Session
. Глава 11. Работа с объектами обсуждает переходные (transient), постоянные (persistent) и отсоединённые (detached) состояния объектов. -
Transaction (
org.hibernate.Transaction
) -
(Опционально) Однопоточный, недолговечный (short-lived) объект, используемый приложением для указания
атомарных единиц работы. Он абстрагирует приложение от базовой транзакции JDBC, JTA или CORBA.
Org.hibernate.Session
может охватывать несколькоorg.hibernate.Transactions
в некоторых случаях. Однако разграничение транзакций, использующее базовый API илиorg.hibernate.Transaction
, никогда не является обязательным. -
ConnectionProvider (
org.hibernate.connection.ConnectionProvider
) -
(Опционально). Фабрика и пул соединений JDBC. Он абстрагирует приложение из основного
javax.sql.DataSource
илиjava.sql.DriverManager
. Он не распространяется на приложение, но может быть расширен и/или реализован разработчиком. -
TransactionFactory (
org.hibernate.TransactionFactory
) -
(Опционально) Фабрика для
org.hibernate.Transaction
. Не распространяется на приложение, но может быть расширена и/или реализована разработчиком. - Расширяемые интерфейсы
- Hibernate предлагает ряд дополнительных интерфейсов расширения, которые вы можете реализовать для настройки поведения вашего уровня персистентности. Подробнее см. В документации по API.
2.2. Контекстные сессии
Большинство приложений, использующих Hibernate, нуждаются в какой-то форме «контекстной» сессии,
где данная сессия действует во всей области данного контекста. Однако во всех приложениях определение
того, что представляет собой контекст, обычно отличается; различные контексты определяют разные области
применения понятия «текущий». Приложения, использующие Hibernate до версии 3.0,
имели тенденцию использовать либо вспомогательные классы на основе ThreadLocal
,
такие как HibernateUtil
, либо использовать сторонние структуры, такие как Spring или Pico,
которые предоставляли контекстные сессии на основе прокси/перехвата (proxy/interception).
Начиная с версии 3.0.1 в Hibernate был добавлен метод SessionFactory.getCurrentSession()
.
Первоначально это предполагаемое использование транзакций JTA, где транзакция JTA определяла как область
видимости, так и контекст текущей сессии. Учитывая зрелость многочисленных автономных реализаций JTA
TransactionManager
, большинство, если не все, приложения должны использовать управление
транзакциями JTA, независимо от того, развертываются ли они в контейнере J2EE.
Исходя из этого, контекстные сессии на основе JTA — все, что вам нужно использовать.
Однако, начиная с версии 3.1, обработка SessionFactory.getCurrentSession()
теперь подключаема.
С этой целью был добавлен новый интерфейс расширения
org.hibernate.context.spi.CurrentSessionContext
и новый параметр конфигурации
hibernate.current_session_context_class
, позволяющие подключать область и контекст
определения текущих сессий.
См. Javadocs, где для интерфейса org.hibernate.context.spi.CurrentSessionContext
подробно
описан его контракт. Он определяет единственный метод currentSession()
,
с помощью которого реализация отвечает за отслеживание текущего контекста сессии. "Из коробки"
Hibernate предоставляет три реализации этого интерфейса:
-
org.hibernate.context.internal.JTASessionContext
: текущие сессии отслеживаются и обрабатываются транзакцией JTA. Обработка здесь точно такая же, как и в более раннем подходе JTA. Подробнее см. Javadocs. -
org.hibernate.context.internal.ThreadLocalSessionContext
: текущие сессии отслеживаются потоком исполнения. Подробнее см. Javadocs. -
org.hibernate.context.internal.ManagedSessionContext
: текущие сессии отслеживаются потоком исполнения. Однако вы несете ответственность за привязку и отвязывание экземпляраSession
со статическими методами в этом классе: он не открывает, не скрывает или не закрывает сессию.
Первые две реализации предоставляют модель программирования «одна сессия — одна база данных».
Или по-другому: сессия-за-запрос (session-per-request). Начало и конец
сессии Hibernate определяется продолжительностью транзакции базы данных. Если вы используете программное
разделение транзакций в простой JSE без JTA, вам рекомендуется использовать Hibernate
Transaction
API, чтобы скрыть базовую систему транзакций из вашего кода.
Если вы используете JTA, вы можете использовать интерфейсы JTA для разделения транзакций.
Если код выполняется в контейнере EJB, который поддерживает CMT, границы транзакций определяются
декларативно, и вам не нужны никакие операции разделения транзакций или сессий в вашем коде.
Более подробную информацию и примеры кода см.
в главе 13 «Транзакции и параллельное выполнение».
Параметр конфигурации hibernate.current_session_context_class
определяет, какая реализация
org.hibernate.context.spi.CurrentSessionContext
должна использоваться. Для обратной совместимости,
если этот параметр конфигурации не установлен, а настроен
org.hibernate.engine.transaction.jta.platform.spi.JtaPlatform
, Hibernate будет использовать
org.hibernate.context.internal.JTASessionContext
. Как правило, значение этого параметра просто
называет класс реализации. Однако для трех готовых реализаций существует три соответствующих коротких имени:
«jta», «thread» и «managed».