使用DerbyDB上的jpa自动生成主键的问题

时间:2010-10-23 10:53:36

标签: jpa primary-key generator derby

我有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;

    ...
}

这一直很好,直到我决定使用以下语法创建带有backuped yaml数据的表:

createNativeQuery("INSERT INTO PLAYERS ...")

成功创建后,我尝试创建一个实体:

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

我收到了错误:

SQL Error: -1, SQLState: 23505 

与primary_keys的重复有关,因为为新实体生成的id = 1(与从备份数据中重新获取的行相同)。当然我可以使用jpa / java语法从备份文件中检索数据,但在这种情况下我无法控制插入数据的主键等。 如何解决这个问题呢 ?在插入备份数据后有没有办法更新id_generator?

1 个答案:

答案 0 :(得分:2)

由于您手动插入数据,因此需要更改表以更改标识列的起始值:

ALTER TABLE PLAYERS ALTER COLUMN ID RESTART WITH 1234;

其中1234是备份数据的最大ID。

ALTER TABLE statement的文档中的更多详细信息:

  

RESTART WITH整数常量   指定下一个值   为标识列生成。   RESTART WITH对表很有用   它有一个标识列   定义为由DEFAULT和。生成   具有在其上定义的唯一键   身份栏。因为GENERATED BY   DEFAULT允许手动插入和   系统生成的值,它是   可能是手动插入的值   可能与系统生成冲突   值。要解决这些冲突,   使用RESTART WITH语法指定   将生成的下一个值   对于标识列。考虑一下   以下示例,其中涉及到   自动生成的组合   数据和手动插入的数据:

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
     

系统会自动生成   标识列的值。但   现在你需要手动插入一些   数据进入标识栏:

INSERT INTO tauto VALUES (3,3)
INSERT INTO tauto VALUES (4,4)
INSERT INTO tauto VALUES (5,5)
     

标识列使用了值1   此时通过5点。??如果你现在   希望系统生成一个值,   系统将生成一个3,其中   将导致唯一的密钥异常   因为价值3已经存在   手动插入。补偿   对于手动插入,发出ALTER   用于标识的TABLE语句   具有RESTART WITH 6的列:

ALTER TABLE tauto ALTER COLUMN i RESTART WITH 6