Hibernate, @SequenceGenerator и allocSize
Мы все знаем поведение Hibernate по умолчанию при использовании@SequenceGenerator
- увеличивает реальную последовательность базы данных наone, умножьте это значение на 50 (по умолчаниюallocationSize
значение) - а затем использует это значение в качестве идентификатора объекта.
Это неправильное поведение и конфликтует сСпецификация который говорит:
allocationSize - (Optional) The amount to increment by when allocating sequence numbers from the sequence.
Чтобы было ясно: я не беспокоюсь о пробелах между сгенерированными идентификаторами.
Я забочусь о идентификаторах, которыеnot consistent с базовой последовательностью базы данных. Например: любое другое приложение (которое, например, использует простой JDBC) может захотеть вставить новые строки под идентификаторами, полученными из последовательности - но все эти значения могут уже использоваться Hibernate! Безумие.
Кто-нибудь знает какое-либо решение этой проблемы (без настройкиallocationSize=1
и, таким образом, снижение производительности)?
EDIT:
Чтобы все было понятно.
Если у последней вставленной записи был ID =1
, то HB используйте значения51, 52, 53...
для его новых объектов, НО в то же время: значение последовательности в базе данных будет установлено равным2
, Что может легко привести к ошибкам, когда другие приложения используют эту последовательность.
С другой стороны: спецификация говорит (в моем понимании), что последовательность базы данных должна была быть установлена в51
и тем временем HB должен использовать значения из диапазона2, 3 ... 50
UPDATE:
Как упомянул Стив Эберсоле ниже: описанное мной поведение (а также наиболее интуитивное для многих) можно включить, установивhibernate.id.new_generator_mappings=true
.
Спасибо всем вам.
UPDATE 2:
Для будущих читателей ниже вы можете найти рабочий пример.
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USERS_SEQ")
@SequenceGenerator(name = "USERS_SEQ", sequenceName = "SEQUENCE_USERS")
private Long id;
}
persistence.xml
<persistence-unit name="testPU">
<properties>
<property name="hibernate.id.new_generator_mappings" value="true" />
</properties>
</persistence-unit>