Hibernate с последовательностью Oracle не использует его - PullRequest
20 голосов
/ 24 августа 2011

Я настроил спящий режим для использования последовательности оракула.Последовательность создается с кешем = 20, приращением = 1.

Все работает нормально, спящие сущности в спящем режиме.Значение id странное: 50,51 .... 76,201,202 ... 209,1008,1009,5129,5130 ....

Если я запрашиваю значение последовательности (выберите hibernate_sequence.nextval из dual)Я получаю значение, как 2,3,4 ....

Если я включаю отладку Hibernate SQL, есть время от времени вызов "выберите hibernate_sequence.nextval from dual", но номер, назначенный Hibernate для ID не 't реле в последовательности!

@Id
@Column(name = "ID", insertable = false, updatable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "HIBERNATE_SEQUENCE")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private Long id;

Ответы [ 3 ]

33 голосов
/ 24 августа 2011

Это потому, что SequenceGenerator на самом деле не генератор последовательности. Это генератор хай-лоу последовательности. Это означает, что при первом вызове он получает следующее значение из последовательности (например, 6), затем умножает это значение на 50 и выдает результат (300). В следующий раз, когда он вызывается, он возвращает 301 (без перехода к последовательности) и т. Д., Пока не достигнет 349. Затем он запрашивает последовательность для следующего значения и получает 7, которое он умножает на 50 снова, чтобы дать вам 350. Мой Описание алгоритма может быть выключено одним, но вы поняли.

Если вы остановите и запустите свое приложение, оно будет иметь пробелы. Но он более эффективен, чем генератор чистой последовательности, потому что он делает вызов базы данных только один раз в 50 поколений.

Подробнее см. http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-enhanced-optimizers и http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#mapping-declaration-id-generator.

6 голосов
/ 24 августа 2011

Я так понимаю, что ваш вопрос в том, что значения столбца ID в базе данных не являются естественной последовательностью, но почему вы видите пробелы:

Немного фона:

  • Каждый раз, когда вы звоните select HIBERNATE_SEQUENCE.nextval from DUAL, значение последовательности увеличивается.
  • Поскольку имя вашей последовательности является общим, а не специфичным для таблицы, если у вас есть несколько сущностей, которые все используют HIBERNATE_SEQUENCE в качестве генератора идентификаторов, то значения из последовательностей используются во всех сущностях.
  • Если какое-то другое приложение использует HIBERNATE_SEQUENCE, то значение также пропускается.
  • Поскольку вы используете CACHE = 20, Oracle будет захватывать порядковые номера в блоках по 20, а затем использовать внутренний кэш для возврата номеров. Это может привести к пропуску чисел в случае потери кеша (например, если БД выключена).
  • Если строки удалены из вашей базы данных, значение последовательности не изменится

Например, рассмотрим следующий сценарий:

У вас есть две сущности Entity1 и Entity2, использующие HIBERNATE_SEQUENCE в качестве генератора идентификаторов:

  1. Текущее значение HIBERNATE_SEQUENCE равно 100
  2. Вставляется Entity1 (использует HIBERNATE_SEQUENCE, который возвращает 101)
  3. Entity2 вставлен (использует HIBERNATE_SEQUENCE, который возвращает 102)
  4. Entity2 вставлен (использует HIBERNATE_SEQUENCE, который возвращает 103)
  5. Объект 2 с идентификатором 103 удален
  6. Вы вручную выполняете select HIBERNATE_SEQUENCE.nextval from DUAL (возвращает 104)
  7. Вставляется Entity1 (использует HIBERNATE_SEQUENCE, который возвращает 105)
  8. Entity2 вставлен (использует HIBERNATE_SEQUENCE, который возвращает 106)

Итак, в конце вы получите:

  • Entity1 с идентификаторами (101, 105)
  • Entity2 с идентификаторами (102, 106)

, что объясняет пробелы.

EDIT:

Даже если @SequenceGenerator был настроен на использование SequenceGenerator вместо SequenceHiLoGenerator (как указал Дж. Б. Низет, который, я думаю, является лучшим объяснением пробелов), пробелы в идентификаторах, генерируемых последовательностями, обычное явление.

0 голосов
/ 28 июля 2016
CREATE SEQUENCE SEQ_SEQUENCENAME INCREMENT BY 1 START WITH 1 MINVALUE 1;
grant all on SEQ_SEQUENCENAME to public;

@Id
@Column(name = "ID", unique = true, nullable = false)
@SequenceGenerator(name = "SequenceIdGenerator", sequenceName = "SEQ_SEQUENCENAME")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SequenceIdGenerator")
private int Id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...