Все мы знаем поведение Hibernate по умолчанию при использовании @SequenceGenerator
- он увеличивает реальную последовательность базы данных на единицу , умножает это значение на 50 (значение по умолчанию allocationSize
), а затем использует это значение в качестве идентификатора объекта.
Это неправильное поведение и противоречит спецификации, которая гласит:
allocationSize - (Необязательно) Сумма увеличения при выделении порядковых номеров из последовательности.
Для ясности: меня не беспокоят пробелы между сгенерированными идентификаторами.
Меня интересуют идентификаторы, которые не соответствуют базовой последовательности базы данных. Например: любое другое приложение (например, использующее простой JDBC) может захотеть вставить новые строки под идентификаторами, полученными из последовательности, но все эти значения могут уже использоваться Hibernate! Безумие.
Кто-нибудь знает какое-либо решение этой проблемы (без настройки allocationSize=1
и, следовательно, снижения производительности)?
РЕДАКТИРОВАТЬ:
чтобы прояснить ситуацию. Если последняя вставленная запись имела ID = 1
, тогда HB использует значения 51, 52, 53...
для своих новых сущностей, НО в то же время: значение последовательности в базе данных будет установлено на 2
. Что может легко привести к ошибкам, когда другие приложения используют эту последовательность.
С другой стороны: в спецификации говорится (в моем понимании), что последовательность базы данных должна быть установлена, 51
а в то же время HB должен использовать значения из диапазона 2, 3 ... 50
ОБНОВЛЕНИЕ:
Как упомянул ниже Стив Эберсол: описанное мной поведение (а также наиболее интуитивное для многих) можно включить, установив hibernate.id.new_generator_mappings=true
.
Спасибо всем вам.
ОБНОВЛЕНИЕ 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>
save
нужно запросить базу данных для следующего значения последовательности.
SequenceGenerator
Hibernate будет запрашивать базу данных только тогда, когда количество идентификаторов, указанных в, allocationsize
заканчивается. Если вы настроили, allocationSize = 1
то это причина, по которой Hibernate запрашивает БД для каждой вставки. Измените это значение, и все готово.
hibernate.id.new_generator_mappings
установка действительно важно. Я надеюсь, что это настройка по умолчанию, и мне не придется тратить так много времени на изучение того, почему идентификационный номер сходит с ума.