如何重新启动由Hibernate处理的PostgreSQL序列?

6

我被指派重新启动PostgreSQL数据库中许多不同串行列的序列。通常,我会简单地使用以下命令:

ALTER SEQUENCE serial RESTART WITH 105;

然而,似乎Hibernate被用来处理数据库序列。我对Hibernate一无所知,但我的理解是hibernate_sequence是所有表的全局序列。这是正确的吗?

那么我认为我需要按照以下步骤进行:

ALTER SEQUENCE hibernate_sequence RESTART WITH 105;

但我不确定后果会是什么。假设我有A、B、C和D四张表,每个表都有一个类型为serial的ID列。那么,上面的SQL语句是否会重置所有表的ID列呢?

谢谢!

1个回答

5
首先,这里存在一个潜在的问题:您正在将序列的值视为有意义的。请参见答案结尾。
现在,使用Hibernate取决于用户如何配置映射。配置良好的Hibernate实例将使用与其他所有内容相同的序列。
不幸的是,大多数映射都不太好 - 或者更确切地说,我认为Hibernate的默认行为很糟糕,应该始终被覆盖。默认使用的序列确实是所有表共享的“hibernate_sequence”。但是,完全可以使一些表使用自己的序列,而其他表使用共享的“hibernate_sequence”,或者使所有表正确地使用自己的序列。
要启用明确的答案,您需要发布映射。
如果您想要更改ID生成的表正在使用其Hibernate映射中的正确序列,则可以直接进行ALTER SEQUENCE该序列。如果您的映射通过JPA完成,则使用GenerationType.SEQUENCE的@SequenceGenerator和@GeneratedValue完成。如果它是通过orm.xml、hbm.xml或旧式Hibernate注释完成的,则需要检查手册。或者,如果Hibernate是唯一编写DB的客户端,请查看序列是否使用SELECT * FROM sequence_name逐步增加。
如果感兴趣的表的映射正在使用共享的“hibernate_sequence”,则可能无法在不修复Hibernate映射的情况下做您想要的事情。您需要更改映射,以便感兴趣的表的映射使用不同的序列,然后锁定表并将这些序列的起始点设置为当前表中最大的行。
序列:为什么需要更改或重新启动序列?这无关紧要,因为合成主键只是一个没有意义的数字,您可以将其与其他没有意义的数字进行比较。您试图解决的问题是什么?

映射是使用JPA完成的,例如,所有类(作为表映射到数据库中)都定义了一个“Integer id = -1”,并与映射一起使用“@GeneratedValue(strategy=GenerationType.SEQUENCE)”进行映射。由于数据库中只有一个序列(hibernate_sequence),并且在所有不同的表中ID值之间存在间隙,因此我认为默认序列在所有表之间共享,正如您所提到的那样。由于某些冲突需要避免,在数据库传输之前需要重新启动所有这些表的序列。 - littleK
1
@littleK 没问题。希望能有所帮助。合并数据库...嗯..."有趣"。特别有趣。希望你买了很多琴酒。 - Craig Ringer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接