Хотя этот вопрос очень стар, и я наткнулся на него для моих собственных проблем с JPA 2.0 и Oracle.
Хотите поделиться мое исследование на некоторые вещи -
Отношения между @SequenceGenerator (allocationSize) из GenerationType.ПОСЛЕДОВАТЕЛЬНОСТЬ и Инкримента в определении последовательности базы данных
Убедитесь @SequenceGenerator (allocationSize) устанавливается на тот же величину, Инкримента в определении последовательности базы данных, чтобы избежать проблем. Для примера. если мы определим последовательность в базе данных с INCREMENT BY значением 20, установите allocationsize в SequenceGenerator также на 20. В этом случае JPA не будет делать вызов в базу данных до тех пор, пока она не достигнет следующей отметки 20, пока она увеличивает каждое значение на 1 внутренне. Это экономит вызовы базы данных для получения следующего порядкового номера каждый раз. Побочным эффектом этого является: при каждом повторном развертывании приложения или перезапуске сервера он будет вызывать базу данных для получения следующей партии, и вы увидите подсказки в значениях последовательности. Также нам нужно убедиться, что определение базы данных и параметр приложения будут синхронизированы, которые могут быть недоступны все время, так как оба они управляются разными группами, и вы можете быстро потерять контроль над ними. Если значение базы данных меньше, чем распределение, вы увидите ошибки ограничения PrimaryKey из-за повторяющихся значений Id. Если значение базы данных выше, чем allocationsize, вы увидите подсказки в значениях Id.
Если последовательность записей INCREMENT BY установлена в 1 (что обычно используется администраторами баз данных), установите allocSize как 1, чтобы они были синхронизированы, но база данных JPA вызывает каждый последующий порядковый номер.
Если вы не хотите звонить в базу данных каждый раз, используйте команду GenerationType.IDENTITY и укажите значение @Id, заданное триггером базы данных. С GenerationType.IDENTITY как только мы называем em.persist объекта сохраняются в БД и значение идентификатора присваиваются возвращенным объект, поэтому мы не должны делать em.merge или ет .flush. (Это может быть поставщик JPA specific..Not уверен)
Еще одна важная вещь -
JPA 2.0 автоматически запускает ALTER SEQUENCE команду для синхронизации allocationSize и Инкримент в последовательности базы данных. В основном мы используем другое имя схемы (Application имя пользователя), а не фактическую схему, где последовательность существует и имя пользователя приложения не будет иметь права SEQUENCE ALTER, вы можете увидеть ниже предупреждение в логах -
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 Продолжительность W CWWJP9991W: openjpa.Runtime: Предупреждение: The свойство «openjpa.jdbc.DBDictionary = disableAlterSeqenceIncrementBy»является значения ИСТИНЫ. Это означает, что„ALTER SEQUENCE ... INCREMENT BY“SQL заявления не будет выполняться в последовательности„RECORD_ID_SEQ“. OpenJPA выполняет эту команду, чтобы убедиться, что увеличивают последовательности пути значения определенно в базе данных соответствует значению allocationSize, который определен в последовательности хозяйствующего субъекта. при этом SQL заявлении отключенного, это ответственности пользователя, чтобы убедиться, что определение последовательности в лице соответствует последовательности, определенной в базе данных.
Как отмечено в предупреждении, важно здесь, чтобы убедиться, что @SequenceGener ator.allocationSize и INCREMENT BY в определении последовательности базы данных синхронизируются, включая значение по умолчанию @SequenceGenerator (allocSize), которое равно 50. В противном случае это вызовет ошибки.
Поставщик JPA (например, Hibernate) будет использовать значение последовательности в качестве базы и * mutiply * его с allocSize, чтобы получить фактический идентификатор, который он будет вставлять. Поэтому, если следующее значение seq равно 11, а allocSize равно 20, следующий сгенерированный идентификатор будет 220. Обычно вы просто хотите, чтобы ваши идентификаторы соответствовали точно значению последовательности, поэтому установите allocSize = INCREMENT BY последовательности. См. Также http://stackoverflow.com/questions/5346147/hibernate-oracle-sequence-produces-large-gap –
Это не работает для столбцов без id. –