Manually insert Data from database in table which has hibernate_sequence @GeneratedValue(strategy = GenerationType.TABLE)

huangapple go评论86阅读模式
英文:

Manually insert Data from database in table which has hibernate_sequence @GeneratedValue(strategy = GenerationType.TABLE)

问题

我有一个带有ID的表,使用@GeneratedValue(strategy = GenerationType.TABLE)。需要在PostgreSQL生产数据库中手动插入800条记录。我们从Oracle迁移到PostgreSQL,一些用户错误地访问了旧链接,并且数据被插入了Oracle数据库。请解释在这种情况下如何维护hibernate_sequence。因为这是生产数据库。

英文:

I have table with ID @GeneratedValue(strategy = GenerationType.TABLE). Need to insert 800 records manually on postgresql production database.We had migration from oracle to postgresql , few User mistakenly access old link and data inserted in oracle . Please explain how to maintain hibernate_sequence in this case. As its production database.

答案1

得分: 1

在第一步中,检查您的密钥生成表和 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;
-- 记住 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

英文:

In the first step check your key generation table and the SEQUENCE_NAME.

If you use the default setting you will see something as follows - adapt the further steps for different configuration.

select * from hibernate_sequences;

SEQUENCE_NAME   NEXT_VAL
--------------- ----------
default         nnnnn

Now increase the NEXT_VAL by the requested number of the skipped records. To avoid the problem of concurent insert via Hibernate I use LOCK TABLE - all insert from Hibernate are blocked until you finish the action bellow.

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;

Now you have 800 ID's nnnn + 1 .. nnnn + 800 to be used for your skipped rows.

Note that the LOCK will work if you connect with the OWNER of the table hibernate_sequences. You may skip the LOCK at all if the application is down and no insert can be performed.

Use the identical INSERT as you see in Hibernate show_sql and with your data pass the reserved ID.

Example

-- 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);

Warning

As mentioned in comment, you should plan to switch to SEQUENCE mapping, which would make the adding of skipped rows even simpler. See also why-you-should-never-use-the-table-identifier-generator-with-jpa-and-hibernate.

Having said that, the TABLE generator could work fine for some use cases e.g. with low number of concurrent inserts. Using similar argumentation the claim could be: why-you-should-never-use-the-jpa-and-hibernate if performance matter.

huangapple
  • 本文由 发表于 2020年4月9日 21:05:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/61121870.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定