Hibernate SequenceGenerator возвращает неверный nextval
Это мой второй пост о спящем режиме. С тех пор, как я начал использовать hibernate, он породил больше проблем, чем решил. Это почти заставляет меня чувствовать, что я должен был придерживаться простого старого JDBC. Тем не мение,
Вот одна из проблем, с которыми я пытаюсь бороться.
Мой генератор последовательностей в файлах.hbm выглядит следующим образом.
<id name="id" type="long" column="ID">
<generator class="sequence">
<param name="sequence">ADVENTURES_ID_SEQ</param>
<param name="allocationSize">1</param>
<param name="initialValue">17599</param>
</generator>
</id>
Обратите внимание: начальное значение 17599. Это потому, что LAST_NUMBER в последовательности оракула: 17599
CREATED 25-APR-12
LAST_DDL_TIME 25-APR-12
SEQUENCE_OWNER ADVENTURE_ADMIN
SEQUENCE_NAME ADVENTURES_ID_SEQ
MIN_VALUE 1
MAX_VALUE 9999999999999999999999999999
INCREMENT_BY 1
CYCLE_FLAG N
ORDER_FLAG N
CACHE_SIZE 20
LAST_NUMBER 17599
Когда я запускаю код, я вижу следующую последовательность, сгенерированную как 200, 201 в операторе отладки Hibernate.
DEBUG SQL - select ADVENTURES_ID_SEQ.nextval from dual
DEBUG SequenceGenerator - Sequence identifier generated: 201
Я ожидал, что следующее значение должно быть 17600. Похоже, что последовательность оракула вообще не используется.
Что не так в моей конфигурации и как это исправить. Любая помощь с благодарностью.
Спасибо
1 ответ
Self Answer (обходной путь): я все еще вижу проблему, но пока у меня есть обходной путь. Поскольку это сработало для меня, я выбираю вопрос как завершенный.
Я позволяю Oracle генерировать nextId с помощью Trigger:
create or replace
TRIGGER ADVENTURE_ADMIN.ADVENTURES_ID_TRIG
BEFORE INSERT ON ADVENTURE_ADMIN.ADVENTURES FOR EACH ROW
WHEN (new.ID IS NULL)
BEGIN
SELECT ADVENTURES_ID_SEQ.NEXTVAL INTO :new.ID FROM DUAL;
END;
Затем я позволяю hibernate использовать идентификатор, сгенерированный Oracle Trigger. Есть два способа сделать это.
Сначала используется Hibernate select. Недостаток этого подхода в том, что вам понадобится еще один столбец в таблице с уникальным ограничением, который используется в спящем режиме в качестве ключа для извлечения строки. Это на самом деле не работает для меня, так как у меня есть таблицы с первичным ключом в качестве единственного уникального ключа.
Второе - использование TriggerAssignedIdentityGenerator, созданного Жаном-Полем Ландрейном, Мартином Зелтнером. Источник можно найти здесь. Это позволило мне обойти проблему поиска другого уникального ключа для таблицы.
Вот как я это использую:
<id name="id" type="long" column="ID">
<generator class="org.hibernate.id.TriggerAssignedIdentityGenerator" />
</id>
Обратите внимание: Hibernate версия, которую вы используете, имеет значение. Я использую 3.5.4. Hibernate 3.6 не работал для меня. Версия JDBC и Oracle Driver также имеет значение. Вы можете обратиться к документации в исходном файле для того же.