Я пытаюсь подготовить интеграционный тест с тестовыми данными. Я читаю вставки запросов из внешнего файла и выполняю их как собственные запросы. После вставки я выполняю select setval('vlan_id_seq', 2000, true );
, Вот определение идентификатора объекта:
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy = IDENTITY)
private Integer id;
Когда я пытаюсь сохранить новую запись, я получил Caused by: org.postgresql.util.PSQLException: ERROR: duplicate key value violates unique constraint "vlan_pkey" Detail: Key (id)=(1) already exists.
исключение. Идентификатор последовательности - 2000. Определение столбца выполняется serial
макросом и является id integer NOT NULL DEFAULT nextval('vlan_id_seq'::regclass)
.
Я выполнил собственные запросы в пользовательской транзакции, поэтому все тестовые записи хранятся в базе данных postgresql, но кажется, что hibernate не синхронизирует последовательность. entityManager.flush();
также не принудительно синхронизировала последовательность. Кажется, что спящий режим не использовал последовательности с @GeneratedValue(strategy = IDENTITY)
. Я использую XA-Datasource и wildfly 13.
Я проверил теперь другой метод инициализации. Я определил сценарий данных SQL (я сгенерировал скрипт с Jailer) в файле persitence.xml(javax.persistence.sql-load-script-source
) и закончил сценарий с помощью select pg_catalog.setval('vlan_id_seq', (SELECT max(id) FROM vlan), true );
, Я устанавливаю точку останова перед первой командой persist, проверяю последовательность в postgresql db, последовательность имеет максимальное значение id 16. Теперь сохраняющиеся работы и запись имеют идентификатор 17. Скрипты выполняются до того, как администратор сущности запускается и спящий режим прочитайте обновленные последовательности во время запуска. Но это решение не ответило на мой вопрос.
Есть ли вероятность, что hibernate перечитывает последовательности для использования значения nextval?
если стратегия Identity означает, что hibernate создаст таблицу последовательностей и выберет идентификаторы из нее, используя собственный sql, вы просто вставляете свои собственные значения без обновления этой таблицы, чтобы у вас было два решения
select currval('vlan_id_seq')
я получал 2000.