Автогенерация первичного ключа JPA

моя сущность первичного ключа выглядит как ниже

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

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

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

но когда я просто заменить на

@GeneratedValue 
private Long id;

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

2 ответов


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

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

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

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

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

EDIT: ответ на комментарий от OP о 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;

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


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

  • авто
  • личность
  • последовательность
  • таблица

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

Это пример того, как использовать стратегию последовательности:

  @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.