【问题标题】:Insert SQL enum with jOOQ in PostgreSQL database在 PostgreSQL 数据库中插入带有 jOOQ 的 SQL 枚举
【发布时间】:2021-08-01 21:50:00
【问题描述】:

我正在尝试使用 jOOQ 在我的数据库中插入一个 SQL 枚举。

数据库迁移是使用 Liquibase 设置的,例如:

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">

    <changeSet id="202105031559" author="pk">
        <sql>CREATE TYPE my_type AS ENUM ('TYPE_A', 'TYPE_B')</sql>

        <createTable tableName="a">
            <column name="type" type="my_type" defaultValue='TYPE_A'>
                <constraints nullable="false"/>
            </column>
        </createTable>
        
    </changeSet>

</databaseChangeLog>

迁移中的默认枚举值按预期工作。

尝试使用jOOQ插入枚举:

var result = dslContext
        .insertInto(A,
                A.TYPE
        )
        .values(
                MyType.TYPE_B
        )
        .execute();

触发错误:

org.postgresql.util.PSQLException: ERROR: column "type" is of type my_type but expression is of type character varying
  Hint: You will need to rewrite or cast the expression.

我的 jOOQ 配置如下所示:

@Configuration
public class JooqConfig {

    private final DataSource dataSource;

    public JooqConfig(DataSource dataSource) {
        this.dataSource = dataSource;
    }
    
    @Bean
    public DataSourceConnectionProvider connectionProvider() {
        return new DataSourceConnectionProvider(new TransactionAwareDataSourceProxy(dataSource));
    }

    @Bean
    public DefaultDSLContext dsl() {
        Settings settings = new Settings()
                .withRenderNameCase(RenderNameCase.LOWER)
                .withRenderQuotedNames(RenderQuotedNames.NEVER)
                .withExecuteLogging(true);
        return new DefaultDSLContext(connectionProvider(), SQLDialect.POSTGRES, settings);
    }

}

我的 Gradle 设置:

jooq {
    version.set(dependencyManagement.importedProperties["jooq.version"])
    edition.set(nu.studer.gradle.jooq.JooqEdition.OSS)

    configurations {
        create("main") {
            jooqConfiguration.apply {
                generator.apply {
                    database.apply {
                        name = "org.jooq.meta.extensions.liquibase.LiquibaseDatabase"
                        withProperties(
                            org.jooq.meta.jaxb.Property()
                                .withKey("scripts")
                                .withValue("src/main/resources/db/changelog/changelog-ddl.xml"),
                            org.jooq.meta.jaxb.Property()
                                .withKey("includeLiquibaseTables")
                                .withValue("false"),
                            org.jooq.meta.jaxb.Property()
                                .withKey("database.liquibaseSchemaName")
                                .withValue("public"),
                            org.jooq.meta.jaxb.Property()
                                .withKey("changeLogParameters.contexts")
                                .withValue("!test"),
                        )
                    }
                }
            }
        }
    }
}

有人知道如何使用 jOOQ 插入枚举吗?

【问题讨论】:

    标签: java postgresql spring-boot gradle jooq


    【解决方案1】:

    从 jOOQ 3.15 开始,org.jooq.meta.extensions.liquibase.LiquibaseDatabase 将 DDL 语句转换为 H2 并模拟内存 H2 数据库上的迁移。这意味着您不能使用供应商特定的 PostgreSQL 功能(H2 支持枚举,但它们有很多缺陷)。

    相反,推荐的方法是使用testcontainers 和一个实际的 PostgreSQL 数据库来生成代码。此问题中记录了有关如何执行此操作的一些想法:https://github.com/jOOQ/jOOQ/issues/6551 或在此示例中:https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples/jOOQ-testcontainers-example

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-03
      • 2016-09-30
      • 2013-08-16
      • 2016-09-01
      • 2012-02-06
      • 2023-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多