我有一个ID为@GeneratedValue(strategy = GenerationType.TABLE)的表。需要在postgresql生产数据库中手动插入800条记录。我们从oracle迁移到postgresql,一些用户错误地访问了旧链接并将数据插入了oracle。请解释如何在这种情况下维护hibernate_sequence。由于这是生产数据库,请注意。
SEQUENCE_NAME
。select * from hibernate_sequences;
SEQUENCE_NAME NEXT_VAL
--------------- ----------
default nnnnn
现在将 NEXT_VAL
增加所请求的跳过记录数。为了避免通过 Hibernate 进行并发插入的问题,我使用了 LOCK TABLE
- 所有来自 Hibernate 的插入都会被阻塞,直到您完成下面的操作。
lock table hibernate_sequences in exclusive mode;
select * from hibernate_sequences;
-- remember the value of NEXT_VAL nnnn
update hibernate_sequences
set NEXT_VAL = NEXT_VAL + 800
where SEQUENCE_NAME = 'default';
commit;
现在你有800个ID
,编号为nnnn + 1 .. nnnn + 800,可用于跳过的行。
请注意,如果您使用表hibernate_sequences
的所有者连接,则LOCK
将起作用。如果应用程序关闭且无法执行插入操作,则可以完全跳过LOCK
。
使用与Hibernate show_sql
中相同的INSERT
,并通过数据传递保留的ID。
例如
-- Hibernate: insert into AUTHOR (name, AUTHOR_ID) values (?, ?)
insert into AUTHOR (name, AUTHOR_ID) values ('Psik', nnnn +1);
insert into AUTHOR (name, AUTHOR_ID) values ('Tuzka', nnnn+2);
警告
正如评论中所提到的,您应该计划切换到SEQUENCE
映射,这将使跳过行的添加变得更加简单。另请参见为什么您绝不应使用JPA和Hibernate的表标识生成器。
话虽如此,TABLE
生成器对某些用例可能很好用,例如具有较低并发插入数量的情况。使用类似的论证,可以声称:如果性能重要,那么您绝不应使用JPA和Hibernate。