【问题标题】:Use Sequence created by Flyway in JPA在 JPA 中使用 Flyway 创建的序列
【发布时间】: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 进行批量插入的能力。

标签: postgresql spring-boot jpa flyway


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2019-03-03
    • 2012-03-20
    • 2018-10-06
    • 2019-01-09
    • 2013-05-29
    • 1970-01-01
    • 2016-10-27
    • 2021-05-13
    • 2019-02-26
    相关资源
    最近更新 更多