Проблема с автоматически сгенерированным primary_key с использованием jpa на DerbyDB - PullRequest
1 голос
/ 23 октября 2010

У меня есть класс сущностей, аннотированный jpa:

@Configurable
@Entity
@Table(name="PLAYERS")
public class Player
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="ID")
    private Integer id;
    @Column(name="NAME")
    private String name;

    @PersistenceContext
        public transient EntityManager entityManager;

    ...
}

Это работало нормально, пока я не решил создать таблицу с резервными копиями данных yaml, используя такой синтаксис:

createNativeQuery("INSERT INTO PLAYERS ...")

После успешного создания, когда я пытаюсь создать объект с:

Player player = new Player();
player.setName("new player");
player.persist();

я получил ошибку:

SQL Error: -1, SQLState: 23505 

относится к дублированию primary_keys, поскольку идентификатор, сгенерированный для нового объекта = 1 (аналогично строке, полученной из резервных данных). Конечно, я могу получить данные из файла резервной копии, используя синтаксис jpa / java, но в этом случае я не могу контролировать первичные ключи вставленных данных и т. Д. Как решить эту проблему ? Есть ли способ обновить id_generator после вставки резервных данных?

1 Ответ

2 голосов
/ 23 октября 2010

Поскольку вы вставляли данные вручную, вам нужно изменить таблицу, чтобы изменить начальное значение столбца идентификаторов:

ALTER TABLE PLAYERS ALTER COLUMN ID RESTART WITH 1234;

Где 1234 - это максимальный идентификатор ваших резервных данных.

Более подробная информация содержится в документации оператора ALTER TABLE :

RESTART WITH целочисленная константа определяет следующее значение, которое будет генерируется для столбца идентификаторов. RESTART WITH полезен для стола который имеет столбец идентичности, который был определяется как ПОЛУЧЕНО ПО УМОЛЧАНИЮ и который имеет уникальный ключ, определенный на этом столбец идентичности. Потому что DEFAULT допускает как ручные вставки, так и система генерирует значения, это возможно, что вручную вставленные значения может конфликтовать с системой генерируется ценности. Чтобы обойти такие конфликты, используйте синтаксис RESTART WITH, чтобы указать следующее значение, которое будет сгенерировано для столбца идентификации. Рассмотрим Следующий пример, который включает в себя комбинация автоматически генерируется данные и данные, вставленные вручную:

<b>CREATE TABLE tauto(i INT GENERATED BY DEFAULT AS IDENTITY, k INT)
CREATE UNIQUE INDEX tautoInd ON tauto(i)
INSERT INTO tauto(k) values 1,2</b>

Система автоматически сгенерирует значения для столбца идентификации. Но Теперь вам нужно вручную вставить некоторые данные в столбце идентификации:

<b>INSERT INTO tauto VALUES (3,3)
INSERT INTO tauto VALUES (4,4)
INSERT INTO tauto VALUES (5,5)</b>

В столбце идентификаторов использованы значения 1 через 5 в этот момент. Если ты сейчас хотите, чтобы система генерировала значение, система сгенерирует 3, который приведет к исключению уникального ключа потому что значение 3 уже было вставляется вручную. Компенсировать для ручных вставок, выпустите ALTER ТАБЛИЦА заявления для личности колонка с перезапуском с 6:

<b>ALTER TABLE tauto ALTER COLUMN i RESTART WITH 6</b>
...