Hibernate генерирует отрицательные значения идентификатора при использовании последовательности - PullRequest
32 голосов
/ 25 марта 2012

У меня есть класс со следующим определением:

@Id
@SequenceGenerator(name = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", sequenceName = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", allocationSize = 500)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ACE_WORKERS_QUEUE_STATS_ID")
@Column(name = "ID")
private long Id;

Когда мы запускали его на Jboss 4.2.3, он работал нормально и генерировал правильные идентификаторы (начиная с 1000+)

Теперь мы перешли на jboss 7.1.1, и он генерирует отрицательные идентификаторы!(начиная с -498 и далее)

Есть идеи, почему это может произойти?

Ответы [ 3 ]

66 голосов
/ 26 сентября 2013

Новое поведение:

AllocationSize - это диапазон значений первичного ключа, зарезервированных для Hibernate.И выбор seq.nextval из двойного будет сделан только после того, как hibernate использует этот диапазон первичных ключей.

Таким образом, вы должны объявить одно и то же значение как для allocationSize (Hibernate), так и для последовательностиincrement by (DB)

Когда явно задано значение allocationSize=500, например, в Oracle

create sequence SEQ_ACE_WORKERS_QUEUE_STATS_ID
       MINVALUE 1 
       MAXVALUE 999999999999999999999999999 
       START WITH 1
       INCREMENT BY 500 
       NOCACHE 
       NOCYCLE;

В противном случае вы заметите отрицательные значения или ошибки ограничения, возникшие в вашей БД из-за первичного ключаколлизии.

При перезапуске сервера приложений вы заметите «скачок» между последним выделенным первичным ключом и «новым» порядковым номером, выбранным при перезапуске.

Последний комментарий:значение по умолчанию - 50. Поэтому, если вы не укажете allocationSize на стороне Hibernate, вы должны объявить increment by 50 на стороне БД.

33 голосов
/ 18 мая 2012

Я только что столкнулся с этой проблемой при переходе с JBoss 6.1 на JBoss 7.1.

Согласно документации JPA JBoss AS 7.1 (https://docs.jboss.org/author/display/AS71/JPA+Reference+Guide#JPAReferenceGuide-Persistenceunitproperties),

JBoss 7.1 автоматически устанавливает несколько свойств гибернации. Одним из устанавливаемых свойств является hibernate.id.new_generator_mappings, которое активирует новые генераторы идентификаторов, которые используют разные алгоритмы и не имеют обратной совместимости. Если установить для этого свойства значение false в файле persistence.xml, восстановится поведение старого генератора идентификаторов.

Документация hibernate 4 также содержит информацию о новых генераторах идентификаторов: http://docs.jboss.org/hibernate/core/4.0/manual/en-US/html_single/#mapping-declaration-id-generator.

Документация hibernate четко заявляет, что новые генераторы идентификаторов не включены по умолчанию, но, как отмечалось выше, JBoss 7.1 автоматически включает их.

22 голосов
/ 03 мая 2013

Установка hibernate.id.new_generator_mappings в false в моем persistence.xml была только первой частью решения моей проблемы:

Чтобы полностью решить проблему, я добавил allocationSize к 1 в @SequenceGenerator (который я опускал).

...