Всі ми знаємо поведінку Hibernate за замовчуванням при використанні @SequenceGenerator
- вона збільшує реальну послідовність баз даних на одиницю , кратне це значення на 50 (значення за замовчуванням allocationSize
) - і потім використовує це значення як ідентифікатор сутності.
Це неправильна поведінка та суперечить специфікації, яка говорить:
dodjeleSize - (необов'язково) Сума, що збільшується при розподілі порядкових номерів із послідовності.
Щоб було зрозуміло: я не переймаюся розбіжностями між створеними ідентифікаторами.
Я дбаю про ідентифікатори, які не відповідають основній послідовності бази даних. Наприклад: будь-яка інша програма (яка, наприклад, використовує звичайний JDBC), може захотіти вставити нові рядки під ідентифікаторами, отриманими з послідовності, - але всі ці значення вже можуть використовувати Hibernate! Божевілля.
Хтось знає якесь рішення цієї проблеми (без встановлення allocationSize=1
і, таким чином, погіршення продуктивності)?
EDIT:
Щоб все було зрозуміло. Якщо останній вставлений запис мав ID = 1
, то НВ 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;
}
стійкість.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.id.new_generator_mappings
установка дійсно важливо. Я би сподівався, що це налаштування за замовчуванням, що мені не доведеться витрачати стільки часу на дослідження, чому ідентифікаційний номер стає дивним.