Как правильно настроить поле @Id, когда таблица базы данных уже заполнена JPA - PullRequest
3 голосов
/ 14 ноября 2011

В моей базе данных есть одна таблица, и я добавил атрибут @Id над полем. В качестве strategy я использую GenerationType.IDENTITY. Это прекрасно работает, когда таблица базы данных еще не заполнена строками из сценария SQL.

Как мне заставить его работать, когда в таблице уже есть несколько строк? Потому что это не работает, когда я пытаюсь вставить сущности из моего приложения, когда оно предварительно заполнено.

Я использую базу данных Derby для этого и eclipselink в качестве реализации.

Ответы [ 2 ]

3 голосов
/ 14 ноября 2011

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

@Id
@GeneratedValue(generator = "yourTableIdGenerator")
@GenericGenerator(name = "yourTableIdGenerator", strategy = "org.hibernate.id.enhanced.SequenceStyleGenerator", parameters = {
                    @Parameter(name = "sequence_name", value = "your_table_id_seq"),
                    @Parameter(name = "optimizer", value = "hilo"),
                    @Parameter(name = "initial_value", value = "1000"),
                    @Parameter(name = "increment_size", value = "10") }
                )
@Column(name = "your_table_id", length = 15)
public Long getId() {
    return id;
}

Установите значение initial_value, превышающее максимальный идентификатор строк, заполненных сценарием.

Из Java 6 EE API: http://download.oracle.com/javaee/6/api/javax/persistence/TableGenerator.html

@TableGenerator(
   name="empGen",
   table="ID_GEN",
   pkColumnName="GEN_KEY",
   valueColumnName="GEN_VALUE",
   pkColumnValue="EMP_ID",
   initialValue = 1000,
   allocationSize=1)
@Id
@GeneratedValue(strategy=TABLE, generator="empGen")
int id;
2 голосов
/ 15 ноября 2011

Я предполагаю, что ваша ошибка в том, что созданная вами таблица IDENTITY начинается (например) с "1", и вы уже заполнили таблицу строкой с идентификатором "1". Так что обязательно существует нарушение PK Constraint. Если это сценарий, я могу предложить:

  1. Проверьте количество строк для предварительного заполнения данных. По примеру 3500.
  2. Создайте столбец идентификаторов в старшем числе, чтобы избежать нарушения ограничения PK, например, следующая таблица запускает идентификатор в 4000:

Это должно работать в Derby DB

CREATE TABLE MAPS    (
    MAP_ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 4000, INCREMENT BY 1),
    MAP_NAME VARCHAR(24) NOT NULL,
    REGION VARCHAR(26),
    AREA DECIMAL(8,4) NOT NULL,
    PHOTO_FORMAT VARCHAR(26) NOT NULL,
    PICTURE BLOB(102400),
    UNIQUE (MAP_ID, MAP_NAME)
)
...