Руководство для начинающих по переходам между состояниями в JPA/Hibernate

Введение

Hibernate меняет тип мышления программиста от SQL выражений к переходам между состояниями сущности. Когда какая-то сущность управляется Hibernate, все изменения буду автоматически распространяться в БД.
Манипуляции с сущностями из доменной модели (вместе с их связями) намного легче чем писать и поддерживать SQL выражения.

Без ORM инструмента добавление нового столбца требует выполнение INSERT/UPDATE выражений.
Но Hibernate не является серебрянной пулей конечно же. Hibernate не освобождает нас от забот по поводу актуальности выполняемых SQL выражений. Управление Hibernate не прямолинейно как могло показаться и обязательно нужно проверять все SQL выражения, который он выполняет у нас за спиной.

Состояния сущностей

Как я уже упомянул, Hibernate наблюдает за прикрепленными сущностями. Но для того чтобы сущность стала обслуживаемой, она должна быть в правильном состоянии.
Сначала мы дадим определения всем состояниям сущности:

  • New (Transient)

Только созданный объект, который никогда не был связан с сессией Hibernate (так же известной как Persistence Context.) и не маппированный на какую нибудь строку в таблице БД находится в состоянии New (Transient) .

  • Persistent (Managed)

Персистентная сущность связана со строкой в таблице БД и обслуживается текущим Persistence Context. Любые изменения совершенные с этой сущностью будут обнаружены и распространены в БД ( в течение Session flush-time). С Hibernate мы больше не должны выполнять INSERT/UPDATE/DELETE выражения. Он использует подход transactional write-behind и изменения синхронизируются в самый последний момент, в течении текущего Session flush-time.

  • Detached

Как только текущий запущенный Persistence Context закрывается все предыдущие обслуживаемые объекты становятся detached. Последующие изменения больше не будут отслеживаться  и не будут происходить автоматическая синхронизация с БД.

Для соединения detached сущности к активной Hibernate Session можно выбрать следующие варианты:

1) Повторное связывание

Hibernate (кроме JPA 2.1) поддерживает повторное присоединение через  Session#update метод.

Hibernate Session может только присоединить один объект сущности для конкретной строки в БД. Это происходит потому что Persistence Context действует как in-memory кэш (кэш первого уровня) и только одно значение (сущность) связано с конкретным ключом (тип сущности и идентификатор в БД).

Сущность может повторно присоединена только если не существует больше никакого другого объекта в JVM (соответсвующий той же строке в БД) уже присоединенного к текущей Hibernate Session.

2) Слияние

Операция слияния копирует состояние  detached сущности (источник) в  обслуживаемый экземпляр сущности (пункт назначения). Если для сущности которая будет сливаться не существует эквивалент в текущей сессии, то одно один экземпляр будет извлечен из БД,

Экземпляр detached объекта будет и дальше оставаться в состоянии detached даже после операции слияния.

  • Removed 

Хотя стандарт JPA  требует что только обслуживаемые сущности могут быть удалены, Hibernate так же удаляет detached сущности (но только через вызов метода Session#delete).

Удаляемая сущность запланирована для удаления и фактический DELETE запрос к БД будет произведен в течении Session flush-time.

Переходы между состояниями

Для изменения состояний одной сущности нужно использовать один из приведенных интерфейсов управления сущностями:

Эти интерфейсы определяют методы для переходов между состояниями и их нужно явно вызывать в Hibernate для изменения состояния сущности. Во время flush-time переход материализуется в DML запрос к БД,

 

(Visited 2 092 times, 1 visits today)

Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.