JPA автогенерация первичного ключа - PullRequest
15 голосов
/ 30 ноября 2009

мой первичный ключевой объект выглядит так

@GeneratedValue(strategy= GenerationType.TABLE)
private Long id;

когда я бегу, я получаю ошибку

не удалось получить или обновить следующее значение, вложенное исключение - org.hibernate.exception.SQLGrammerException: не удалось получить или обновить следующее значение

но когда я просто перехожу на

@GeneratedValue 
private Long id;

без ошибок. Я хочу создать уникальный первичный ключ для каждой таблицы на oracle db.

Ответы [ 2 ]

29 голосов
/ 30 ноября 2009

@GeneratedValue(strategy=GenerationType.TABLE) указывает провайдеру JPA использовать таблицу для получения идентификаторов при вставке вновь созданных объектов в базу данных.

При использовании Hibernate в качестве поставщика это приведет к таблице hibernate_sequences, которая имеет два столбца: имя объекта и максимальный идентификатор, уже назначенный этому объекту. Здесь, похоже, Hibernate не удалось получить следующий идентификатор для вашей сущности, но трудно сказать точно, почему, потому что вы не предоставили достаточно информации для этого.

Итак, не могли бы вы предоставить полную трассировку стека? Также, пожалуйста, включите ведение журнала со свойством hibernate.show_sql, установленным на true, и установите правильный уровень ведения журнала log4j.logger.org.hibernate.SQL=DEBUG. Если возможно, присоедините журнал к своему вопросу.

Может быть, просто проверьте, что вы правильно настроили hibernate.dialect для Oracle. На самом деле, если возможно, присоединитесь к своей конфигурации гибернации.

PS: «Традиционный» способ генерации PK с Oracle - это использовать последовательности (вы можете позволить Hibernate угадать лучшую стратегию для вашего типа базы данных, используя GenerationType.AUTO, или принудительно использовать SEQUENCE), но я предполагаю, что вы хотите, чтобы результирующая структура данных была независимой от базы данных. Если нет, я бы посоветовал перейти к последовательностям.

РЕДАКТИРОВАТЬ: Ответ на комментарий от ОП о GenerationType.AUTO. Действительно, по умолчанию используется единственная глобальная последовательность с именем hibernate_sequence, и это может быть проблемой. Но с настройкой, показанной ниже, вы можете использовать GenerationType.AUTO и по-прежнему контролировать имя последовательности для случаев, когда база данных использует последовательности:

@Id
@GeneratedValue(strategy=GenerationType.AUTO, generator="my_entity_seq_gen")
@SequenceGenerator(name="my_entity_seq_gen", sequenceName="MY_ENTITY_SEQ")
private long id;

Другими словами, вы можете использовать разные имена последовательностей для каждой таблицы без потери переносимости.

9 голосов
/ 22 декабря 2014

В JPA есть 4 стратегии для автоматической генерации:

  • Авто
  • Идентичность
  • Последовательность
  • Таблица * * 1 010

Для аннотации первичного ключа автоматического генерирования Oracle, Sequence и Table - ваш выбор. Основная логика - сначала определить генератор, использовать @ SequenceGenerator или @ TableGenerator соответственно, а затем использовать генератор в качестве атрибута в @GeneratedValue.

Это пример использования стратегии Sequence:

  @Id
  @SequenceGenerator(name="SEQ_GEN", sequenceName="SEQ_JUST_FOR_TEST", allocationSize=1)
  @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_GEN")
  private long id;

Вот пример использования стратегии таблицы:

  @Id
  @TableGenerator(name="TABLE_GEN",table="T_GENERATOR", pkColumnName = "GEN_KEY", pkColumnValue = "MONITOR2012.T_JUST_FOR_TEST", valueColumnName = "GEN_VALUE", initialValue = 1, allocationSize = 1 )
  @GeneratedValue(strategy = GenerationType.TABLE, generator="TABLE_GEN")
  private long id;

Если в аннотации @ GeneratedValue не указан генератор, выбор остается за реализацией JPA.

Если вы работаете с базой данных с существующими таблицами, убедитесь, что вы используете последовательность или таблицу, определенную в базе данных, прежде чем запускать ваше приложение. Генератору таблиц также понадобится вставить строку в таблицу, прежде чем аннотация @GeneratedValue сможет работать правильно.

Вот учебник о , как настроить автоматическую генерацию первичного ключа в JPA для базы данных Oracle .

...