【问题标题】:Problem with auto-generated primary_key using jpa on DerbyDB在 Derby DB 中使用 jpa 自动生成主键的问题
【发布时间】:2010-10-23 10:53:36
【问题描述】:

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

【问题讨论】:

    标签: jpa primary-key generator derby


    【解决方案1】:

    因为是手动插入数据,所以需要修改表来改变标识列的起始值:

    ALTER TABLE PLAYERS ALTER COLUMN ID RESTART WITH 1234;
    

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

    更多细节在ALTER TABLE statement的文档中:

    使用整数常量重新启动 指定下一个值 为标识列生成。 RESTART WITH 对表很有用 有一个身份列是 定义为默认生成和 上面定义了一个唯一键 身份列。因为生成于 DEFAULT 允许手动插入和 系统生成的值,它是 可能手动插入值 可能与系统生成的冲突 价值观。为了解决此类冲突, 使用 RESTART WITH 语法来指定 将生成的下一个值 对于身份列。考虑 以下示例,其中涉及 自动生成的组合 数据和手动插入数据:

    CREATE TABLE tauto(i INT 由默认身份生成,k INT)
    在 tauto(i) 上创建唯一索引 tautoInd
    插入 tauto(k) 值 1,2

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

    插入 tauto 值 (3,3)
    插入 tauto 值 (4,4)
    插入 tauto 值 (5,5)

    标识列使用了值 1 在这一点上通过5.??如果你现在 希望系统产生一个值, 系统将生成一个 3,其中 将导致唯一键异常 因为值 3 已经 手动插入.????补偿 对于手动插入,发出 ALTER 身份的 TABLE 语句 RESTART WITH 6 列:

    ALTER TABLE tauto ALTER COLUMN i RESTART WITH 6

    【讨论】:

    • 这正是我所需要的,可以按需要工作。我发现的另一个可能的解决方案是:修改 SYS.SYSCOLUMNS 表中的字段 AUTOINCREMENTVALUE,DerbyDb 使用该字段来存储 primary_key 的最后生成值,但由于这是系统表,因此需要管理员权限。所以这是比较麻烦的解决方案。
    • @user85005:是的,这也可以(但您注意到需要更多权限)。实际上,alter 会导致系统表的修改。使用 alter IMO 更方便。
    猜你喜欢
    • 2010-12-21
    • 2020-10-27
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多