尽管配置,JOOQ 不会忽略未知功能

Posted

技术标签:

【中文标题】尽管配置,JOOQ 不会忽略未知功能【英文标题】:JOOQ not ignoring unknown function despite configuration 【发布时间】:2021-08-24 15:56:14 【问题描述】:

我的 jOOQ 代码生成配置因框架未知的功能而失败。配置使用org.jooq.meta.extensions.ddl.DDLDatabase,旨在从 Flyway 迁移脚本生成代码。错误如下:

Error running jOOQ code generation tool: Error while exporting schema: SQL [create table CUSTOMER (ID uuid not null default UUID_GENERATE_V4(), NAME varchar(255) not null, primary key (ID))]; Function "UUID_GENERATE_V4" not found;

通过查看文档,我看到有一个 parseUnknownFunctions 解析器属性,据我所知,当设置为 IGNORE 时应该禁用此行为。这似乎没有任何效果。

我还知道有一种解决方法可以通过在其上添加 cmets 使 jOOQ 忽略 SQL 文件的某些部分。在我的情况下这是不可能的,因为我不是 SQL 文件的所有者。

我还有其他选择吗?

以下是导致错误的脚本和 pom.xml 中的 jOOQ 配置:

create table customer (
    id   uuid         not null default uuid_generate_v4(),
    name varchar(255) not null,
    primary key (id)
);
<plugin>
  <groupId>org.jooq</groupId>
  <artifactId>jooq-codegen-maven</artifactId>
  <executions>
    <execution>
      <id>generate-jooq-sources</id>
      <phase>generate-sources</phase>
      <goals>
        <goal>generate</goal>
      </goals>
      <configuration>
        <generator>
          <database>
            <name>org.jooq.meta.extensions.ddl.DDLDatabase</name>
            <inputSchema>PUBLIC</inputSchema>
            <outputSchemaToDefault>true</outputSchemaToDefault>
            <outputCatalogToDefault>true</outputCatalogToDefault>
            <properties>
              <property>
                <key>sort</key>
                <value>semantic</value>
              </property>
              <property>
                <key>scripts</key>
                <value>src/main/resources/db/migration/*</value>
              </property>
              <property>
                <key>parseUnknownFunctions</key>
                <value>IGNORE</value>
              </property>
            </properties>
          </database>
          <target>
            <clean>true</clean>
            <packageName>com.product</packageName>
            <directory>$project.generated-sources/jooq/src/main/java</directory>
          </target>
        </generator>
      </configuration>
    </execution>
  </executions>
  <dependencies>
    <dependency>
      <groupId>org.jooq</groupId>
      <artifactId>jooq-meta-extensions</artifactId>
      <version>$jooq.version</version>
    </dependency>
  </dependencies>
</plugin>

【问题讨论】:

【参考方案1】:

如果您查看完整的堆栈跟踪,您会发现错误不是由 jOOQ 引发的,而是由 H2 引发的:

Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Function "UUID_GENERATE_V4" not found; SQL statement:
create table CUSTOMER (ID uuid not null default UUID_GENERATE_V4(), NAME varchar(255) not null, primary key (ID)) [90022-200]
    at org.h2.message.DbException.getJdbcSQLException (DbException.java:576)
    at org.h2.message.DbException.getJdbcSQLException (DbException.java:429)
    at org.h2.message.DbException.get (DbException.java:205)
    at org.h2.message.DbException.get (DbException.java:181)
    at org.h2.command.Parser.readJavaFunction (Parser.java:3565)
    at org.h2.command.Parser.readFunction (Parser.java:3770)
    at org.h2.command.Parser.readTerm (Parser.java:4305)
    at org.h2.command.Parser.readFactor (Parser.java:3343)
    at org.h2.command.Parser.readSum (Parser.java:3330)
    at org.h2.command.Parser.readConcat (Parser.java:3305)
    at org.h2.command.Parser.readCondition (Parser.java:3108)
    at org.h2.command.Parser.readExpression (Parser.java:3059)
    at org.h2.command.Parser.parseColumnForTable (Parser.java:5727)
    at org.h2.command.Parser.parseTableColumnDefinition (Parser.java:8442)
    at org.h2.command.Parser.parseCreateTable (Parser.java:8379)
    at org.h2.command.Parser.parseCreate (Parser.java:6276)
    at org.h2.command.Parser.parsePrepared (Parser.java:903)
    at org.h2.command.Parser.parse (Parser.java:843)
    at org.h2.command.Parser.parse (Parser.java:815)
    at org.h2.command.Parser.prepareCommand (Parser.java:738)
    at org.h2.engine.Session.prepareLocal (Session.java:657)
    at org.h2.engine.Session.prepareCommand (Session.java:595)
    at org.h2.jdbc.JdbcConnection.prepareCommand (JdbcConnection.java:1235)
    at org.h2.jdbc.JdbcStatement.executeInternal (JdbcStatement.java:212)
    at org.h2.jdbc.JdbcStatement.execute (JdbcStatement.java:201)
    at org.jooq.tools.jdbc.DefaultStatement.execute (DefaultStatement.java:102)
    at org.jooq.impl.SettingsEnabledPreparedStatement.execute (SettingsEnabledPreparedStatement.java:227)
    at org.jooq.impl.AbstractQuery.execute (AbstractQuery.java:411)
    at org.jooq.impl.AbstractQuery.execute (AbstractQuery.java:332)
    at org.jooq.meta.extensions.ddl.DDLDatabase.load (DDLDatabase.java:183)
    at org.jooq.meta.extensions.ddl.DDLDatabase.lambda$0 (DDLDatabase.java:156)

DDLDatabase 的当前 (jOOQ 3.15) 实现将您的 DDL 转换为 H2 方言,并在内存数据库中的 H2 中运行它以模拟您的 DDL。 H2 不支持此功能。未来的 jOOQ 版本将在不使用 H2 的情况下解释 DDL(请参阅https://github.com/jOOQ/jOOQ/issues/7034),但目前情况并非如此。

作为一种解决方法,您可以使用此处记录的 jOOQ 解析器忽略注释语法: https://www.jooq.org/doc/latest/manual/code-generation/codegen-ddl/

具体来说:

create table customer (
    id   uuid         not null 
    /* [jooq ignore start] */ default uuid_generate_v4() /* [jooq ignore stop] */,
    name varchar(255) not null,
    primary key (id)
);

或者(更好!)使用此处记录的基于测试容器的方法之一:https://github.com/jOOQ/jOOQ/issues/6551 或在此示例中:https://github.com/jOOQ/jOOQ/tree/main/jOOQ-examples/jOOQ-testcontainers-example

【讨论】:

以上是关于尽管配置,JOOQ 不会忽略未知功能的主要内容,如果未能解决你的问题,请参考以下文章

警告:tensorflow:忽略带有图像 id 的检测,尽管配置参数为真

无法修复 JOOQ 查询中的“未知表”异常

新的 jooq/gradle 配置不生成任何 jooq 类

如何使用 Spring-Boot config 配置 JOOQ 设置?

调试“jOOQ代码生成工具配置错误”

如何从 SQL 查询配置 jOOQ 可嵌入类型