我已经在我的实体类中为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.
现在我脑子里有几个问题:
@GeneratedValue(strategy=GenerationType.IDENTITY)
的理解是否正确?答案 0 :(得分:0)
IDENTITY
表示使用数据存储区功能,如“AUTO_INCREMENT”,“SERIAL”,“IDENTITY”。因此,任何INSERT
都应省略 IDENTITY
列,并在执行INSERT
后将值拉回(存入于该对象的内存中)。INSERT
语句。答案 1 :(得分:0)
我没有使用JPA,但你所拥有的对我来说似乎是合理的。
就DB2 for i而言......
您确定在标识列上收到重复键错误吗?是否没有其他列定义为唯一?
标识列上可能存在重复键错误。
您需要意识到的是,下一个标识值存储在表对象中;没有在飞行中计算。当我开始使用Identities时,我得到了一个CMS包,它通常使用CPYF在新创建的表版本之间移动数据。该表的新版本的下一个标识值为1,即使其中可能有100K记录。 (该软件包已经变得越来越聪明了:)但重点仍然是CPYF,例如,对于标识列并不好玩。
此外,可以通过GENERATED ALWAYS
声明的OVERRIDING SYSTEM VALUE
或OVERRIDING USER VALUE
条款覆盖INSERT
。但是使用覆盖插入对存储的下一个标识值没有影响。我想可以将CPYF视为使用OVERRIDING SYSTEM VALUE
现在,就你遗失的身份而言......
ALTER TABLE <...> ALTER COLUMN <...> RESTART WITH
让我解释一下#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。