Наконец-то я разобрался с этим механизмом.Для hibernate поле @Id обрабатывается в унифицированной процедуре любого типа: если вы хотите, чтобы hibernate сгенерировал для вас значение id, вы должны вызвать session.save, даже значение id может быть определено на этапе создания объекта.
Это проблематично: если пользователь использует UUID в качестве первичного ключа, это означает, что пользователь хочет определить значение до связи с базой данных.Для некоторой сложной логики, после создания объекта A, объект A должен выполнить некоторые дополнительные действия, после этого объект A должен вместе с другим объектом B в транзакции совершить транзакцию в базу данных.Если идентификатор объекта А равен нулю до фиксации базы данных, это очень неудобно из-за того, что объект еще не является законченным объектом.
Hibernate использует процедуру генерации унифицированного идентификатора в качестве предположения, которое используется для определения объекта, является временным илине.Если @GeneratedValue
это add, hibernate считает объект временным, только если значение id равно нулю (это довольно просто, если значение id не равно нулю, тогда необходимо вызвать session.save).Если без генератора hibernate не может знать этот факт, единственный способ выяснить это - выбрать его из базы данных.Поэтому необходимо пропустить @SelectBeforeUpdate (false)
. Единственный способ изменить процедуру - это самостоятельно определить Interceptor, который переопределяет Interceptor.isTransient, однако для этого требуется, чтобы пользователь реализовал проверку переходных процессов.Если в нем всегда возвращается false, сохранение и обновление должны вызываться точно.