使用JPA,如何在H2 db上使用正则列创建生成的列?

发布于 2025-02-07 13:29:28 字数 3696 浏览 1 评论 0原文

我们在大多数环境中使用Liquibase,但是我们使用JPA注释在本地设置H2和单位测试。

我正在努力添加生成的列,但是它没有创建列,也没有丢弃错误。 我使用的注释正常用于默认列,但是生成的列(unique_name)直接忽略了。没有错误,警告或信息消息。

如果我更新应用程序属性配置以显示JPA SQL,则它没有字段。

如果我尝试使用默认而不是生成,它说它看不到名称列:

Column "NAME" not found; SQL statement:
ALTER TABLE security_markings.security_marking
  ADD COLUMN unique_name VARCHAR(255) NOT NULL DEFAULT REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g') UNIQUE [42122-212] 42S22/42122

但是,当我通过H2控制台手动添加列时,它可以正常工作:

ALTER TABLE security_markings.security_marking
  ADD COLUMN unique_name VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE;

实体:

@Getter
@Setter
@NoArgsConstructor
@ToString
@Table(name = "table_name", schema = "schema_name")
@EntityListeners(AuditingEntityListener.class)
public class TableName extends BaseEntity {

    @Column(name = "id", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "UUID NOT NULL DEFAULT random_uuid() UNIQUE")
    private UUID id; //NOTE: This is not the primary key yet, but will be at a future date.

    // FIXME - This is the column that is being ignored.
    @Column(name = "id", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE")
    private String unique_name;

    @Id
    @Column(name = "name", unique = true, nullable = false)
    @NotEmpty(message = "Name is required")
    @NaturalId
    private String name;

请注意,我正在使用v2.1.212弹簧靴的H2和2.5.4:

<properties>
    <h2.version>2.1.212</h2.version>
    <spring-boot.version>2.5.4</spring-boot.version>
</properties>
...
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
...
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

We use Liquibase for most environments, but we use JPA annotations to set up H2 locally and for unit tests.

I'm working on adding a generated column, but it's not creating the column and throws no error.
The annotation I'm using works fine for the DEFAULT column, but the GENERATED column (unique_name) is straight up ignored. No error, warning or info message.

If i update the application properties configs to show JPA SQL, it just doesn't have the field.

If I try to use DEFAULT instead of GENERATED, it says it can't see the name column:

Column "NAME" not found; SQL statement:
ALTER TABLE security_markings.security_marking
  ADD COLUMN unique_name VARCHAR(255) NOT NULL DEFAULT REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g') UNIQUE [42122-212] 42S22/42122

However, when I add the column manually, via the H2 console, it works fine:

ALTER TABLE security_markings.security_marking
  ADD COLUMN unique_name VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE;

Entity:

@Getter
@Setter
@NoArgsConstructor
@ToString
@Table(name = "table_name", schema = "schema_name")
@EntityListeners(AuditingEntityListener.class)
public class TableName extends BaseEntity {

    @Column(name = "id", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "UUID NOT NULL DEFAULT random_uuid() UNIQUE")
    private UUID id; //NOTE: This is not the primary key yet, but will be at a future date.

    // FIXME - This is the column that is being ignored.
    @Column(name = "id", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE")
    private String unique_name;

    @Id
    @Column(name = "name", unique = true, nullable = false)
    @NotEmpty(message = "Name is required")
    @NaturalId
    private String name;

Please note, I am using v2.1.212 of H2 and 2.5.4 of Spring-Boot:

<properties>
    <h2.version>2.1.212</h2.version>
    <spring-boot.version>2.5.4</spring-boot.version>
</properties>
...
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <scope>runtime</scope>
        </dependency>
...
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

被翻牌 2025-02-14 13:29:28

事实证明,问题是复制/粘贴错误。

这两个字段在JPA注释中都具有相同的列名称。一旦我将名称从ID更新为unique_name。问题解决了。

    @Column(name = "id", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE")
    private String unique_name;

变成

    @Column(name = "unique_name", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE")
    private String uniqueName;

Turns out the issue was a copy/paste error.

Both fields had the same column name definded in the JPA annotation. Once I updated the name from id to unique_name. Issue was solved.

    @Column(name = "id", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE")
    private String unique_name;

becomes

    @Column(name = "unique_name", updatable = false, nullable = false, insertable = false, unique = true, columnDefinition = "VARCHAR(255) NOT NULL GENERATED ALWAYS AS (REGEXP_REPLACE(lower(name), '[^a-z0-9]+', '-', 'g')) UNIQUE")
    private String uniqueName;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文