AS400表的JPA序列生成策略IDENTITY

时间:2015-12-17 00:12:21

标签: java hibernate jpa spring-data-jpa ibm-midrange

我已经在我的实体类中为AS400系统中的表的主键提到了序列生成策略IDENTITY。

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "SEQNO")
private Integer seqNo;

表格的主键列在数据库中定义为GENERATED ALWAYS AS IDENTITY。
    SEQNO BIGINT NOT NULL GENERATED ALWAYS AS IDENTITY(START WITH 1, INCREMENT BY 1)
我对IDENTITY策略的理解是它将主键生成责任留给表本身 我面临的问题是,在某种环境中,在表格中插入记录时,它会给我[SQL0803] Duplicate Key value specified. 现在我脑子里有几个问题:

  1. 我对@GeneratedValue(strategy=GenerationType.IDENTITY)的理解是否正确?
  2. 在哪种情况下表会生成Duplicate key?
  3. 我发现表中缺少序列值,即在4之后,缺少20的序列,我不知道是否有人手动删除它,但这是否与重复密钥生成有关?

2 个答案:

答案 0 :(得分:0)

  1. YES。 IDENTITY表示使用数据存储区功能,如“AUTO_INCREMENT”,“SERIAL”,“IDENTITY”。因此,任何INSERT都应省略 IDENTITY列,并在执行INSERT后将值拉回(存入于该对象的内存中)。
  2. 永远不应该获得重复的密钥。检查正在使用的INSERT语句。
  3. 使用同一个表的一些外部进程?使用日志查看SQL并进行处理。

答案 1 :(得分:0)

我没有使用JPA,但你所拥有的对我来说似乎是合理的。

就DB2 for i而言......

您确定在标识列上收到重复键错误吗?是否没有其他列定义为唯一?

标识列上可能存在重复键错误。

您需要意识到的是,下一个标识值存储在表对象中;没有在飞行中计算。当我开始使用Identities时,我得到了一个CMS包,它通常使用CPYF在新创建的表版本之间移动数据。该表的新版本的下一个标识值为1,即使其中可能有100K记录。 (该软件包已经变得越来越聪明了:)但重点仍然是CPYF,例如,对于标识列并不好玩。

此外,可以通过GENERATED ALWAYS声明的OVERRIDING SYSTEM VALUEOVERRIDING USER VALUE条款覆盖INSERT。但是使用覆盖插入对存储的下一个标识值没有影响。我想可以将CPYF视为使用OVERRIDING SYSTEM VALUE

现在,就你遗失的身份而言......

  1. 数据已删除
  2. 使用已覆盖的身份复制数据
  3. 有人ALTER TABLE <...> ALTER COLUMN <...> RESTART WITH
  4. 您失去了使用某些值
  5. 让我解释一下#4。出于性能原因,DB2 for i默认情况下将为要使用的进程缓存20个标识值。因此,如果您有两个进程添加记录,一个将获得值1-20另一个20-40。这允许两个进程同时插入。但是,如果进程1仅插入10条记录,则标识值11-20将丢失。如果您必须具有连续的标识值,请在创建标识期间指定NO CACHE

    create table test
     myid int generated always 
        as identity 
        (start with 1, increment by 1, no cache)
    

    最后,关于身份值的缓存。在确认此答案的一些内容时,我注意到使用ALTER TABLE添加新列似乎会导致缓存值丢失。我插入了3行,做了alter table,下一行的标识值为21。