Liquibase和Hibernate JPA在PostgreSQL和H2中的序列名称不兼容问题。

5

我有一个使用标准Hibernate JPA和Liquibase生成数据库的应用程序。我在测试时使用H2,在运行时使用PostgreSQL。

我的问题是,我似乎无法很好地为序列生成的主键设置此设置。

当我有如下实体id时:

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

使用Liquibase创建数据库,操作步骤如下:

<column name="id" type="BIGINT" autoIncrement="true" incrementBy="1">
    <constraints nullable="false" primaryKey="true" />
</column>

在H2中工作正常,但是对于PostgreSQL,Hibernate抱怨它是:

"Missing sequence or table: hibernate_sequence"

我可以通过将JPA的@GeneratedValue更改为以下内容来解决PostgreSQL的问题:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "text_id_seq")
@SequenceGenerator(name = "text_id_seq", sequenceName = "text_id_seq", allocationSize = 1)
private Long id;

但是现在H2序列与Hibernate所期望的不匹配。
似乎没有简单的方法确保Liquibase使用特定名称的序列。我该怎么做才能使这个设置工作?
看起来我当前正在运行:
- liquibase.version 2.0.4 - hibernate 4.1.7 - postgres driver 9.1-901.jdbc3 - postgres 9.2.1(至少在本地) - h2 1.3.168

1
GenerationType.IDENTITY 怎么样?总的来说,在我看来,这是 JPA 中的一项缺陷;所有这些基于注释的配置使得在目标数据库需要变化时很难进行调整。 - Craig Ringer
感谢@CraigRinger,有点尴尬我没想到去尝试。在H2、pg和mysql上都能完美运行。如果AUTO可以在liquibase和JPA上运行就更好了,但这不是什么大问题。 - storset
1个回答

5
使用 GenerationType.IDENTITY。大多数数据库都可以使用。
在我看来,标识生成是 JPA 的一个问题;它太难设置全局覆盖生成选项基于您使用的数据库等。在注释中进行此操作使得在编程时难以调整。
Hibernate 奇怪的 hibernate_sequence 特别痛苦。我不明白为什么它不使用 PostgreSQL 默认序列来生成列。

刚刚在2023年遇到了完全相同的问题。即使经过了这么长时间,这个解决方案还是有效的。谢谢。 - Beat Luginbühl

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