Если вы используете назначенный генератор, с использованием merge
вместо persist
может вызвать избыточный оператор SQL , что повлияет на производительность.
Также, вызовобъединение для управляемых объектов также является ошибкой, поскольку Hibernate автоматически управляет управляемыми объектами, и их состояние синхронизируется с записью базы данных с помощью механизма грязной проверки после сброса контекста постоянства ,
Чтобы понять, как все это работает, вы должны сначала знать, что Hibernate переключает мышление разработчика с операторов SQL на переходы состояний сущности .
Когда Hibernate активно управляет сущностью, все изменения будут автоматически распространяться в базу данных.
Hibernate отслеживает подключенные объекты.Но для того, чтобы сущность стала управляемой, она должна находиться в правильном состоянии сущности.
Сначала мы должны определить все состояния сущности:
New (Transient)
Вновь созданный объект, который никогда не был связан с Hibernate Session
(он же Persistence Context
) и не сопоставлен ни с одной строкой таблицы базы данных, считается находящимся в состоянии New (Transient).
Чтобы стать постоянным, нам нужно либо явно вызвать метод EntityManager#persist
, либо использовать транзитивный механизм персистентности.
Постоянный (управляемый)
Постоянный объект был связан со строкой таблицы базы данных, и он управляется текущим текущим контекстом постоянства.Любое изменение, внесенное в такой объект, будет обнаружено и распространено в базу данных (во время сброса сеанса).С Hibernate нам больше не нужно выполнять операторы INSERT / UPDATE / DELETE.Hibernate использует рабочий стиль с транзакционной записью , и изменения синхронизируются в самый последний ответственный момент, во время текущего Session
времени сброса.
Detached
Как только текущий запущенный контекст постоянства закрывается, все ранее управляемые объекты становятся отсоединенными.Последовательные изменения больше не будут отслеживаться, и автоматическая синхронизация базы данных не будет выполняться.
Чтобы связать отдельную сущность с активным сеансом Hibernate, вы можете выбрать один из следующих параметров:
Повторное подключение
Hibernate (но не JPA 2.1) поддерживает повторное подключение через метод обновления Session #.Сеанс Hibernate может связать только один объект Entity для данной строки базы данных.Это связано с тем, что постоянный контекст действует как кэш в памяти (кэш первого уровня) и только одно значение (сущность) связано с данным ключом (тип сущности и идентификатор базы данных).Сущность может быть повторно присоединена, только если нет другого объекта JVM (соответствующего той же строке базы данных), уже связанного с текущим сеансом Hibernate.
Объединение
Слияние собирается скопировать состояние отдельного объекта (источник) в экземпляр управляемого объекта (место назначения).Если объединяемый объект не имеет эквивалента в текущем сеансе, он будет выбран из базы данных.Экземпляр отсоединенного объекта будет оставаться отсоединенным даже после операции слияния.
Удалено
Хотя JPA требует, чтобы разрешалось удалять только управляемые объекты, Hibernate также можетудалить отдельные объекты (но только через вызов метода Session # delete).Удаленный объект запланирован только для удаления, и фактический оператор DELETE базы данных будет выполнен во время сброса сеанса.
Чтобы лучше понять переходы состояния JPA, вы можете визуализировать следующую диаграмму:
Или, если вы используете специальный API Hibernate: