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 также имеет значение. Вы можете обратиться к документации в исходном файле для того же.

Другие вопросы по тегам