Хотя этот вопрос очень старый, и я наткнулся на него из-за собственных проблем с последовательностями JPA 2.0 и Oracle.
Хочу поделиться своим исследованием некоторых вещей -
Отношение между @ SequenceGenerator (allocSize) из GenerationType.SEQUENCE и INCREMENT BY в определении последовательности базы данных
Убедитесь, что @ SequenceGenerator (allocSize) имеет то же значение, что и INCREMENT BY в определении последовательности базы данных, чтобы избежать проблем (то же самое относится и к начальному значению).
Например, если мы определим последовательность в базе данных со значением INCREMENT BY, равным 20, установите для параметра allocationsize в SequenceGenerator также значение 20. В этом случае JPA не будет выполнять вызов базы данных, пока не достигнет следующих 20 отметок, пока он увеличивает каждое значение на 1 внутри. Это сохраняет вызовы базы данных, чтобы каждый раз получать следующий порядковый номер.
Побочный эффект этого - всякий раз, когда приложение повторно развертывается или сервер перезапускается между ними, он вызывает базу данных для получения следующего пакета, и вы увидите скачки в значениях последовательности. Также нам нужно убедиться, что определение базы данных и настройки приложения синхронизированы, что может быть невозможно все время, поскольку обе они управляются разными группами, и вы можете быстро потерять контроль над ними. Если значение базы данных меньше, чем размер размещения, вы увидите ошибки ограничения PrimaryKey из-за повторяющихся значений Id. Если значение базы данных больше, чем размер размещения, вы увидите скачки значений Id.
Если для последовательности базы данных INCREMENT BY задано значение 1 (что обычно делают администраторы баз данных), установите для параметра allocSize также значение 1, чтобы они были синхронизированы, но JPA каждый раз вызывает базу данных для получения следующего порядкового номера.
Если вы не хотите каждый раз вызывать базу данных, используйте стратегию GenerationType.IDENTITY и установите значение @Id, установленное триггером базы данных. С GenerationType.IDENTITY , как только мы вызываем em.persist , объект сохраняется в БД, и возвращаемому объекту присваивается значение id, поэтому нам не нужно делать em.merge или em.flush . (Это может зависеть от поставщика JPA .. Не уверен)
Еще одна важная вещь -
JPA 2.0 автоматически запускает команду ALTER SEQUENCE для синхронизации allocSize и INCREMENT BY в последовательности базы данных. Поскольку в основном мы используем другое имя схемы (имя пользователя приложения), а не реальную схему, в которой существует последовательность, а имя пользователя приложения не будет иметь привилегий ALTER SEQUENCE, в журналах может появиться следующее предупреждение -
000004c1 Runtime W CWWJP9991W: openjpa.Runtime: Warn: Unable
кэшировать значения последовательности для последовательности "RECORD_ID_SEQ". Ваш
Приложение не имеет разрешения на запуск команды ALTER SEQUENCE.
Убедитесь, что у него есть соответствующее разрешение на запуск ALTER SEQUENCE
команда.
Поскольку JPA не может изменить последовательность, JPA каждый раз вызывает базу данных для получения следующего порядкового номера независимо от значения @ SequenceGenerator.allocationSize. Это может быть нежелательным последствием, о котором нам нужно знать.
Чтобы JPA не запускала эту команду, установите это значение в файле persistence.xml. Это гарантирует, что JPA не будет пытаться выполнить команду ALTER SEQUENCE. Это пишет другое предупреждение, хотя -
00000094 Runtime W CWWJP9991W: openjpa.Runtime: Предупредить:
свойство "openjpa.jdbc.DBDictionary = disableAlterSeqenceIncrementBy" является
установить в true. Это означает, что SQL «ALTER SEQUENCE ... INCREMENT BY»
Оператор не будет выполнен для последовательности "RECORD_ID_SEQ". OpenJPA
выполняет эту команду, чтобы гарантировать, что значение INCREMENT BY последовательности
определенный в базе данных, соответствует allocSize, который определен в
последовательность объекта. С этим оператором SQL отключен, это
ответственность пользователя за обеспечение последовательности объектаопределение соответствует последовательности, определенной в базе данных.
Как отмечается в предупреждении, здесь важно убедиться, что @ SequenceGenerator.allocationSize и INCREMENT BY в определении последовательности базы данных синхронизированы, включая значение по умолчанию @SequenceGenerator (allocSize), равное 50. В противном случае это приведет к ошибки.