2012-03-27 2 views
4

Я использую спящий режим с JBoss 4.2.3 и все работает, теперь я мигрировал код для Jboss 7.1.1 и вдруг я начинаю получать:Hibernate бросает ошибку нарушения PK

Caused by: org.hibernate.exception.ConstraintViolationException: ORA-00001: unique constraint (OBLICORE.PK_ACE_WORKERS_QUEUE_STATS_ID) violated 

Также генерируемое Идентификаторы являются отрицательными.

Лицо, которое не определяется как таковой:

@Id 
@SequenceGenerator(name = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", sequenceName = "SEQ_ACE_WORKERS_QUEUE_STATS_ID", allocationSize = 500) 
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ACE_WORKERS_QUEUE_STATS_ID") 
@Column(name = "ID") 
private long Id; 

Я проверил последовательность в Oracle и, кажется, в порядке (Как я уже сказал, он работал раньше с JBoss 4.2 и ничего не изменилось на стороне БД, так как миграция).

Я пробовал записывать журналы запросов Hibernate, но не смог найти этот запрос, и я также зарегистрировал конкретный вызов, который сохраняется в этом классе, и увидел, что он вызван только один раз.

ответ

7

Проверить этот вопрос: hibernate oracle sequence produces large gap

Она должна быть последовательность генератор Hibernate, который по умолчанию использует алгоритм Привет/Lo, и возвращаемые значения переполнены. Вы можете попробовать использовать аннотацию, зависящую от гибернации, по умолчанию для более старого поведения GenericGenerator(name="blah", strategy="sequence") или установить allocationSize=1.

Если вы полагаетесь на свою последовательность, увеличивающуюся на некоторое значение, превышающее 1, вам придется использовать другой генератор. Или, может быть, достаточно установить hibernate.id.new_generator_mappings на false, но это входит в сферу действия нового вопроса.

+0

Огромное спасибо, я так долго ударил головой об этом. – Tomer

+0

allocSize = 1 не работает для меня, но strategy = "sequence" работает как шарм – Hamedz

0

Если сгенерированное значение id не так критично в вашем проекте, попробуйте использовать @GeneratedValue(strategy = GenerationType.AUTO) , эта стратегия автоматически генерирует идентификатор, увеличивая последнее на единицу. Надеюсь, это будет полезно для вас.

+0

У меня очень большой проект со многими файлами, которые используют последовательности, и продукт уже развернут на многих сайтах клиентов (это версия 8), поэтому я не могу вносить изменения, как мне заблагорассудится, я должен придерживаться что у меня есть. – Tomer

1

Когда мы изменили Hibernate использовать новый генератор, я использовал следующий сценарий, чтобы исправить последовательности:

DECLARE 
    v NUMBER; 
    BEGIN 
    FOR r IN (select sequence_name from user_sequences) LOOP 
     EXECUTE IMMEDIATE 'ALTER SEQUENCE '|| r.sequence_name ||' INCREMENT BY 50'; 
     EXECUTE IMMEDIATE 'SELECT '|| r.sequence_name ||' .NEXTVAL FROM DUAL' INTO v; 
    END LOOP; 
    END; 
/

Если allocationSize 500, вы должны изменить «Инкримент 50» на «Инкримент 500" .