JOOQ 不生成类(JPADatabase)

Posted

技术标签:

【中文标题】JOOQ 不生成类(JPADatabase)【英文标题】:JOOQ does not generating classes (JPADatabase) 【发布时间】:2021-01-27 02:13:15 【问题描述】:

我在使用 JOOQ 框架 (3.13.5) 以及 Spring Boot 和 Java 8 时遇到问题。我正在尝试按照作者页面 (link) 上给出的手册中的说明使用 GenerationTool 来自 JOOQ,提到了here。项目结构如下:

domain 包包含 JPA 实体。然后我添加了运行配置,作为主类,我用参数标记了 JOOQ 库中的 GenerationTool:/jooq-config.xml(如上面链接的作者手册中所述)。配置文件内容如下图:

<configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.13.0.xsd">
<generator>
    <database>
        <name>org.jooq.meta.extensions.jpa.JPADatabase</name>
        <properties>
            <property>
                <key>packages</key>
                <value>com.ormtester.jpa.domain</value>
            </property>
            <property>
                <key>useAttributeConverters</key>
                <value>true</value>
            </property>
            <property>
                <key>unqualifiedSchema</key>
                <value>none</value>
            </property>
            <property>
                <key>hibernate.physical_naming_strategy</key>
                <value>org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy</value>
            </property>
        </properties>
    </database>
</generator>

对于分析问题,我还添加了带有 lib 版本的 pom.xml 片段:

<dependencies>
    <dependency>
        <groupId>org.jooq</groupId>
        <artifactId>jooq-meta-extensions</artifactId>
        <version>3.13.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.3.4.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>$lombok.version</version>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.jooq</groupId>
        <artifactId>jooq-codegen</artifactId>
        <version>3.13.5</version>
    </dependency>
</dependencies>

现在当我尝试构建项目时,出现以下错误:

18:49:37.330 [main] WARN org.jooq.util.jaxb.tools.MiniJAXB - org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 72; cvc-elt.1: Cannot find the declaration of element 'configuration'.
18:49:42.215 [main] INFO org.jooq.codegen.GenerationTool - Initialising properties  : /jooq-config.xml
18:49:43.134 [main] DEBUG org.jooq.codegen.GenerationTool - Input configuration      : <onError>FAIL</onError><generator><name>org.jooq.codegen.DefaultGenerator</name><database><name>org.jooq.meta.extensions.jpa.JPADatabase</name><regexMatchesPartialQualification>true</regexMatchesPartialQualification><sqlMatchesPartialQualification>true</sqlMatchesPartialQualification><includes>.*</includes><excludes></excludes><includeExcludeColumns>false</includeExcludeColumns><includeTables>true</includeTables><includeEmbeddables>true</includeEmbeddables><includeRoutines>true</includeRoutines><includeTriggerRoutines>false</includeTriggerRoutines><includePackages>true</includePackages><includePackageRoutines>true</includePackageRoutines><includePackageUDTs>true</includePackageUDTs><includePackageConstants>true</includePackageConstants><includeUDTs>true</includeUDTs><includeSequences>true</includeSequences><includeIndexes>true</includeIndexes><includePrimaryKeys>true</includePrimaryKeys><includeUniqueKeys>true</includeUniqueKeys><includeForeignKeys>true</includeForeignKeys><includeCheckConstraints>true</includeCheckConstraints><includeInvisibleColumns>true</includeInvisibleColumns><recordVersionFields></recordVersionFields><recordTimestampFields></recordTimestampFields><syntheticIdentities></syntheticIdentities><syntheticPrimaryKeys></syntheticPrimaryKeys><overridePrimaryKeys></overridePrimaryKeys><dateAsTimestamp>false</dateAsTimestamp><ignoreProcedureReturnValues>false</ignoreProcedureReturnValues><unsignedTypes>true</unsignedTypes><integerDisplayWidths>true</integerDisplayWidths><inputCatalog></inputCatalog><outputCatalogToDefault>false</outputCatalogToDefault><inputSchema></inputSchema><outputSchemaToDefault>false</outputSchemaToDefault><schemaVersionProvider></schemaVersionProvider><catalogVersionProvider></catalogVersionProvider><orderProvider></orderProvider><forceIntegerTypesOnZeroScaleDecimals>true</forceIntegerTypesOnZeroScaleDecimals><logSlowQueriesAfterSeconds>5</logSlowQueriesAfterSeconds><logSlowResultsAfterSeconds>5</logSlowResultsAfterSeconds><properties><property><key>packages</key><value>com.ormtester.jpa.domain</value></property><property><key>useAttributeConverters</key><value>true</value></property><property><key>unqualifiedSchema</key><value>none</value></property><property><key>hibernate.physical_naming_strategy</key><value>org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy</value></property></properties></database></generator>
Exception in thread "main" java.lang.NoSuchMethodError: org.jooq.meta.jaxb.Configuration.getBasedir()Ljava/lang/String;
    at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:272)
    at org.jooq.codegen.GenerationTool.run(GenerationTool.java:225)
    at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:220)
    at org.jooq.codegen.GenerationTool.main(GenerationTool.java:192)

但是,当我删除 jooq-config.xml 文件时,错误直接告诉我找不到配置文件。

我尝试调试 GenerationTool 方法,但找不到问题所在。我无法指定问题的根源,因此我将感谢您的每一个帮助。提前致谢!

【问题讨论】:

启动mvn dependency:tree 并检查jooq-codegenjooq-meta 的已解决版本。它们符合您的期望吗? @Lesiak 这两个库的版本与 pom 文件中定义的版本完全相同 - 3.13.5。 让我们先排除明显的错误:尝试在 IntelliJ 中“重新加载所有 Maven 项目”。 org.jooq.meta.jaxb.Configuration.getBasedir() 返回一个String 是在jooq-meta:3.13.5 中定义的,所以一定是某种项目设置错误 @Lesiak 我已经做过很多次了(包括现在完全准确的尝试),即使 IDEA 的缓存失效和错误仍然相同。 好的,来自jooq-meta:3.12.3Configuration 没有getBasedir() 方法,因此这解释了错误。我的猜测是你有一些由 spring 设置的版本管理,它覆盖了3.13.5。请分享整个pom.xml 【参考方案1】:

Spring boot 引入了一组默认的 jOOQ 库版本,您可以使用您在 cmets 中获得的指令进行验证(主要是 mvn dependency:tree)。您收到的错误提示您的类路径中存在不兼容的版本。

如果您自己的版本与 spring boot 引入的不同,您可能需要告诉 spring boot 不要引入任何 jOOQ 版本,并将它们全部引入自己,例如使用这种方法documented in this blog post here

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jooq</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.jooq</groupId>
      <artifactId>jooq</artifactId>
    </exclusion>
  </exclusions>
</dependency>

【讨论】:

【参考方案2】:

好的,按照@Lukas 和@Lesiak 在本主题中给出的提示,我已经找到了解决方案。正如您在初始 pom 的内容中看到的那样,我添加了 jooq-codegenjooq-meta-extensions 保留版本 3.13.5 并且我确信“在幕后”这些依赖项持有相同版本的 jooq 和 @ 987654326@ 库,但不幸的是在这两种情况下都有3.12.3。所以首先我检查了来自@Lukas 的提示,然后我必须从依赖项中排除这些库,并使用正确的版本号将它们添加为单独的依赖项。

我也在谈论jooq(最初的问题只是jooq-meta),因为在Configuration 类的问题得到解决后,我也遇到了与`org.jooq 类似的问题。 SQLDialect,如下:

java.lang.NoSuchMethodError: org.jooq.SQLDialect.supportedBy([Lorg/jooq/SQLDialect;)Ljava/util/Set; 在 org.jooq.meta.AbstractDatabase.(AbstractDatabase.java:117) 在 java.lang.Class.forName0(Native Method) 在 java.lang.Class.forName(Class.java:264) 在 org.jooq.codegen.GenerationTool.loadClass0(GenerationTool.java:983) 在 org.jooq.codegen.GenerationTool.loadClass(GenerationTool.java:930) 在 org.jooq.codegen.GenerationTool.run0(GenerationTool.java:395) 在 org.jooq.codegen.GenerationTool.run(GenerationTool.java:225) 在 org.jooq.codegen.GenerationTool.generate(GenerationTool.java:220) 在 org.jooq.codegen.GenerationTool.main(GenerationTool.java:192)

正如我所说,它还伴随着版本不匹配,在这种情况下是jooq

在所有这些更改之后,我的 pom 的内容是:

<dependencies>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq</artifactId>
            <version>3.13.5</version>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-meta-extensions</artifactId>
            <version>3.13.5</version>
            <exclusions>
                <exclusion>
                    <groupId>org.jooq</groupId>
                    <artifactId>jooq</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.jooq</groupId>
                    <artifactId>jooq-meta</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-meta</artifactId>
            <version>3.13.5</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>2.3.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>$lombok.version</version>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.jooq</groupId>
            <artifactId>jooq-codegen</artifactId>
            <version>3.13.5</version>
            <exclusions>
                <exclusion>
                    <groupId>org.jooq</groupId>
                    <artifactId>jooq</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.jooq</groupId>
                    <artifactId>jooq-meta</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.jibx</groupId>
            <artifactId>jibx-tools</artifactId>
            <version>1.3.1</version>
        </dependency>
    </dependencies>

在这里我可以给你一个小提示 - 如果你有一个以复数形式命名的表并且你想快速将它们去复数以保持生成的类的名称是单数的,你必须从 pom 的 sn-p 添加最后一个依赖,创建您自己的扩展DefaultGeneratorStrategy 的类,并使用以下片段覆盖getJavaClassName() 方法的主体:

String javaClassName = super.getJavaClassName(definition, mode);
        boolean hasRecordSuffix = javaClassName.contains("Record");
        javaClassName = javaClassName.replace("Record", "");
        String val = nameTools.depluralize(javaClassName);
        if (hasRecordSuffix)
            val += "Record";
        return val;

然后只需将您的自定义命名策略添加到 xml 配置。像魅力一样工作,使用这个项目: link

我真的很感谢你,@Lukas 和 @Lesiak,感谢您的帮助!

【讨论】:

以上是关于JOOQ 不生成类(JPADatabase)的主要内容,如果未能解决你的问题,请参考以下文章

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

Jooq codegen 不生成类

jOOQ 不生成源

Jooq 生成视图类

jOOQ 不使用自定义数据绑定

如何配置 pom.xml 以将 jooq 类生成到两个不同的包中?