如何在数据库表已填充JPA时正确设置@Id字段

时间:2011-11-14 13:19:47

标签: java java-ee jpa derby

我在数据库中有一个表,并在字段中添加了@Id属性。作为strategy我使用GenerationType.IDENTITY。当数据库表尚未填充SQL脚本中的行时,这很正常。

如果表中已经有一些行,我怎么能设法让它工作?因为当我尝试从预先填充的应用程序中插入实体时,它不起作用。

我正在使用Derby数据库和eclipselink作为实现。

2 个答案:

答案 0 :(得分:3)

使用序列生成器从序列表中获取其ID。像这样:

@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设置为大于从脚本填充的行的最大ID的值。

来自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;

答案 1 :(得分:2)

我将假设您的错误是因为您为您创建的IDENTITY表(例如)在“1”中启动,并且您已经使用ID为“1”的行填充了表。所以肯定存在PK约束违规。如果这是我可以建议的情景:

  1. 检查预填充数据的行数。以示例3500。
  2. 在高级编号中创建标识列以避免PK约束违规,例如下表在4000中启动标识:
  3. 这应该适用于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)
    )