【问题标题】:Primary key violation issue oracle db主键违规问题 oracle db
【发布时间】:2022-01-13 10:16:55
【问题描述】:

目前我正在将一列数据迁移到新表中,并创建了一个序列来生成这样的主键

CREATE SEQUENCE seq_my_generated
  MINVALUE 1
  MAXVALUE 99999999
  START WITH 1
  INCREMENT BY 1

我使用以下脚本迁移数据

INSERT INTO my_new_table( new_table_pk, old_table_pk_as_fk, attachment) SELECT seq_my_generated.nextval, old_table_pk, attachment FROM old_table

到那时一切正常,现在在实际环境中,新数据将通过我的 java 应用程序插入到新表中,我的新表的 Java 代码如下所示

@Entity
@Table(name="my_new_table")
public class NewTable{

@Id
@GeneratedValue(strategy = SEQUENCE, generator ="seq_my_generated")
@SequenceGenerator(name="seq_my_generated")
@Column(name="new_table_pk")
long id;
//rest parameters
}

现在,当我尝试通过应用程序插入新数据时,主键唯一性违规异常, 我的假设是,当我使用 db 脚本迁移数据时,我的 java 代码不知道使用的最后一个值是什么,因此它尝试重用表中已经存在的相同键 谁能告诉我我的假设是否正确或可能是什么问题?

【问题讨论】:

    标签: oracle spring-data-jpa spring-data oracle-sqldeveloper


    【解决方案1】:

    好吧,您可以通过选择下一个序列值并检查它是否已存在于表中来验证您的假设。


    或者 - 并且可能更好 - 重新创建序列。首先,找到最大主键列的值:

    select max(new_table_pk) from my_new_table;
    

    假设它返回了2254

    然后创建序列为最大PK列值+1

    SQL> create sequence seq_my_generated start with 2255;
    
    Sequence created.
    
    SQL> select seq_my_generated.nextval from dual;
    
       NEXTVAL
    ----------
          2255
    
    SQL>
    

    因此,当您下次运行您的代码时,将不再有任何重复。

    【讨论】:

    • 好吧,您可以通过选择下一个序列值并检查它是否已存在于表中来验证您的假设。 -- 如何通过我的代码?
    • 如果“你的代码”是指“你的 Java 代码”,那么我不知道,我不会说 Java。从 SQL 开始,然后获取下一个序列值并 - 使用 SELECT 语句 - 查看它是否存在。如果是这样,取另一个序列值并重复(显然,在循环中,这意味着 PL/SQL,而不是 SQL)。
    【解决方案2】:

    根据this 文章 我的 db 序列中的增量大小为 1,默认情况下,spring-jpa 中的分配大小为 50,这意味着每 50 次计数它查询 db 以获取新 id,因为我从 db 脚本迁移数据直到我的 50 计数我的 spring -jpa 不会去查询数据库,所以我在我的序列生成器中更改了我的 allocationSize=1,这解决了我的问题

    【讨论】:

      猜你喜欢
      • 2014-05-12
      • 2015-05-08
      • 2011-04-19
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-28
      相关资源
      最近更新 更多