在 JPA 中使用 Flyway 创建的序列

Posted

技术标签:

【中文标题】在 JPA 中使用 Flyway 创建的序列【英文标题】:Use Sequence created by Flyway in JPA 【发布时间】:2019-04-02 09:36:39 【问题描述】:

我正在使用 Spring Boot 2 / Flyway / Postgres 设置。

我想实现让Flyway创建一个带有序列的表,用于自动键迭代。 JPA 应该能够识别序列并使用它。

我让 Flyway 执行一个 PostgreSQL 脚本:

CREATE SEQUENCE config_id_seq;

CREATE TABLE config
(
    ID          BIGINT NOT NULL PRIMARY KEY DEFAULT nextval('config_id_seq'),
    DESCRIPTION VARCHAR(500)
);

这是实体定义:

@Entity
@Table(name = "config")
public class Config 

    @Id
    @SequenceGenerator(name = "config_id_sequence", sequenceName = "config_id_seq")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "config_id_sequence")
    @Column(name = "id")
    private long id;

    @Column(name = "description")
    private String description;

在启动时会抛出以下错误:

Caused by: org.postgresql.util.PSQLException: ERROR: relation "config_id_seq" already exists
Caused by: org.postgresql.util.PSQLException: ERROR: cannot change sequence "config_id_seq"

我的解释是 Flyway 成功执行了脚本并创建了一个序列。但是 JPA 想要在之后创建序列并失败,因为它已经存在。如果我在这里错了,请纠正我。

如果可能的话,现在如何配置 JPA 以重用现有序列?

【问题讨论】:

JPA 不使用列的“默认”规范。指定 GeneratedValue 表示 JPA 使用一个序列,检索下一个值本身,然后在 INSERT 中使用它......不是您想要的(您希望从 INSERT 中省略该列,因此它使用默认规范...不可能) @BillyFrost:如果我猜对了,我应该放弃 sequence 和 nextval() 命令并使用 JPA 来执行此操作? 是的。这就是 JPA 的价值生成所需要的。然后它创建序列,并管理对 nextval 的调用 @BillyFrost:很有趣。那么,连接到使用序列来增加 id 的现有数据库的 JPA 方式是什么?即使使用 ddl-auto: none? 作为第二个选项,您可以将生成策略设置为 IDENTITY,这意味着在数据库中设置字段值(用于 auto_increment / serial 类型)。这可能适用于您的情况。这样做虽然您将失去使用 JPA 进行批量插入的能力。 【参考方案1】:

我们需要将 spring.jpa.hibernate.ddl-auto 属性设置为 none 或者您可以跳过此属性,以便 spring 不会自行创建数据库对象。

如果我们使用flyway,那么我们应该只将创建数据库对象的责任交给flyway,即只使用flyway脚本创建所有数据库对象,例如表和序列。

指定 GeneratedValue 表示 JPA 使用序列,检索下一个值本身,然后在 INSERT 中使用它。

但请确保您的配置与您在实体类和 flyway 脚本中提到的配置相同。

【讨论】:

以上是关于在 JPA 中使用 Flyway 创建的序列的主要内容,如果未能解决你的问题,请参考以下文章

在 flyway 迁移脚本之前执行 JPA 表创建

Oracle 中的 JPA 和 Flyway 布尔类型

SpringBoot - Flyway - JPA 集成 - 创建名称为“flywayInitializer”的 bean 时出错 - information_schema 中的未知表“事件”

具有 JPA 依赖关系的 Flyway Spring Boot Autowired Bean

为啥flyway迁移需要JPA依赖才能运行

Flyway 与 JPA + OSGi 的集成