JPA: ошибка InvalidStateException + сгенерированные идентификаторы составного ключа / EmbeddableId / последовательности

В настоящее время у меня настроена схема с моей базой данных и Java-приложением с использованием OpenJPA, которая работает большую часть времени, но иногда я получаю ошибку для нескольких пользователей:

org.apache.openjpa.persistence.InvalidStateException: попытка установить для столбца table1.ID два разных значения.

table1 фактически имеет составной ключ (два значения), и каждое значение в этом ключе является внешним ключом для другой таблицы. Я использовал RSA (Rational Software Architect) для настройки сущностей (сгенерированный код). Он установил класс PK (используя @EmbeddableId для ссылки на класс PK) в классе Entity для table1, а затем две связи @ManyToOne в том же классе Entity table1 (а также в классах сущностей, на которые ссылаются эти столбцы), поскольку они внешние ключи

Как я уже упоминал выше, каждое значение в составном ключе является внешним ключом. Что ж, каждый из этих внешних ключей фактически генерируется с использованием внешнего Sequencer в их собственных классах сущностей. Я использую DB2 и использую @GeneratedValue для столбцов (т. Е. Идентификаторов в классах сущностей table2 и table3). Я также использую стратегию = GenerationType.SEQUENCE для каждого.

Опять же, все работает ОБЫЧНО, но не в 100% случаев, и я не уверен, почему. Я избавился от этой ошибки, удалив все и сбросив генераторы последовательности, но я знаю, что это определенно не решение. Может ли это иметь какое-то отношение к тому факту, что два значения составного ключа в базе данных являются внешними ключами для столбцов, которые были сгенерированы с использованием последовательности, но объект PK может не знать?

Я также заметил, что он работает только для пользователей, у которых есть запись в таблице Users (один из упомянутых выше внешних ключей относится к таблице Users, а другой FK - к другой таблице). Что происходит, если пользователя нет в таблице, он создает ее, что-то вроде:

User newUser = userManager.getNewUser();
newUser.setName(..);
newUser.setEmail(..);
...

Когда это будет сделано, класс PK, о котором я упоминал выше, получит новый экземпляр, который затем вызывается в другую таблицу. Идентификатор указанного выше пользователя передается в ПК. Нравится:

PK newPK = pkManager.getNewPK();
newPk.setAID(newUser.getID());

Кто-нибудь сталкивался с этим? Какие-нибудь решения?


person MAR    schedule 28.08.2011    source источник


Ответы (1)


Извините, проблема исправлена. Я просмотрел свой код и понял, что забыл рефакторинг одной строки кода (изменение модели данных).

person MAR    schedule 29.08.2011