Введение
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 запрос к БД,
клас спс