使用 DDL 数据库生成代码时找不到函数 - jooq
Posted
技术标签:
【中文标题】使用 DDL 数据库生成代码时找不到函数 - jooq【英文标题】:Function not found when generating code with DDL Database - jooq 【发布时间】:2022-01-12 16:38:19 【问题描述】:我有一个带有 mysql 数据库的 spring boot gradle 项目。以前在 jooq 版本 3.13.6 下,我的 sql 被解析没有错误。当更新到更高的 jooq 版本(3.14.X 和 3.15.X)并使用 jooq 生成/解析迁移时,我得到以下输出:
严重的 DDLDatabase 错误:您的 SQL 字符串无法解析或 解释。这可能有多种原因,包括:
jOOQ 解析器不理解您的 SQL jOOQ DDL 模拟逻辑(转换为 H2)无法模拟您的 SQLorg.h2.jdbc.JdbcSQLSyntaxErrorException:找不到函数“coalesce”;
下面给出了发生错误的基本 sql 示例。使用 jooq 3.13.6 解析相同的视图。
DROP VIEW IF EXISTS view1;
CREATE VIEW view1 AS
SELECT COALESCE(SUM(table1.col1), 0) AS 'sum'
FROM table1;
我现在迷路了。我在 jooq 更改日志中没有看到任何相关更改。
非常感谢任何帮助或进一步研究的指导。
扩展堆栈跟踪:
11:10:30 SEVERE DDLDatabase Error : Your SQL string could not be parsed or interpreted. This may have a variety of reasons, including:
- The jOOQ parser doesn't understand your SQL
- The jOOQ DDL simulation logic (translating to H2) cannot simulate your SQL
If you think this is a bug or a feature worth requesting, please report it here: https://github.com/jOOQ/jOOQ/issues/new/choose
As a workaround, you can use the Settings.parseIgnoreComments syntax documented here:
https://www.jooq.org/doc/latest/manual/sql-building/dsl-context/custom-settings/settings-parser/
11:10:30 SEVERE Error while loading file: /Users/axel/projects/service/./src/main/resources/db/migration/V5__create_view1.sql
11:10:30 SEVERE Error in file: /Users/axel/projects/service/build/tmp/generateJooq/config.xml. Error : Error while exporting schema
org.jooq.exception.DataAccessException: Error while exporting schema
at org.jooq.meta.extensions.AbstractInterpretingDatabase.connection(AbstractInterpretingDatabase.java:103)
at org.jooq.meta.extensions.AbstractInterpretingDatabase.create0(AbstractInterpretingDatabase.java:77)
at org.jooq.meta.AbstractDatabase.create(AbstractDatabase.java:332)
at org.jooq.meta.AbstractDatabase.create(AbstractDatabase.java:322)
at org.jooq.meta.AbstractDatabase.setConnection(AbstractDatabase.java:312)
at org.jooq.codegen.GenerationTool.run0(GenerationTool.java:531)
at org.jooq.codegen.GenerationTool.run(GenerationTool.java:237)
at org.jooq.codegen.GenerationTool.generate(GenerationTool.java:232)
at org.jooq.codegen.GenerationTool.main(GenerationTool.java:204)
Caused by: org.jooq.exception.DataAccessException: SQL [create view "view1" as select "coalesce"("sum"("table1"."col1"), 0) "sum" from "table1"]; Function "coalesce" not found; SQL statement:
create view "view1" as select "coalesce"("sum"("table1"."col1"), 0) "sum" from "table1" [90022-200]
at org.jooq_3.15.5.H2.debug(Unknown Source)
at org.jooq.impl.Tools.translate(Tools.java:2988)
at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:639)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:349)
at org.jooq.meta.extensions.ddl.DDLDatabase.load(DDLDatabase.java:183)
at org.jooq.meta.extensions.ddl.DDLDatabase.lambda$export$0(DDLDatabase.java:156)
at org.jooq.FilePattern.load0(FilePattern.java:307)
at org.jooq.FilePattern.load(FilePattern.java:287)
at org.jooq.FilePattern.load(FilePattern.java:300)
at org.jooq.FilePattern.load(FilePattern.java:251)
at org.jooq.meta.extensions.ddl.DDLDatabase.export(DDLDatabase.java:156)
at org.jooq.meta.extensions.AbstractInterpretingDatabase.connection(AbstractInterpretingDatabase.java:100)
... 8 more
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Function "coalesce" not found; SQL statement:
create view "view1" as select "coalesce"("sum"("table1"."col1"), 0) "sum" from "table1" [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.readFunctionParameters(Parser.java:3778)
at org.h2.command.Parser.readFunction(Parser.java:3772)
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.parseSelectExpressions(Parser.java:2931)
at org.h2.command.Parser.parseSelect(Parser.java:2952)
at org.h2.command.Parser.parseQuerySub(Parser.java:2817)
at org.h2.command.Parser.parseSelectUnion(Parser.java:2649)
at org.h2.command.Parser.parseQuery(Parser.java:2620)
at org.h2.command.Parser.parseCreateView(Parser.java:6950)
at org.h2.command.Parser.parseCreate(Parser.java:6223)
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:414)
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:335)
... 16 more
> Task :generateJooq FAILED
Jooq 配置:
jooq
version = "3.15.5"
edition = JooqEdition.OSS
configurations
main
generationTool
generator
name = 'org.jooq.codegen.KotlinGenerator'
strategy
name = 'org.jooq.codegen.DefaultGeneratorStrategy'
generate
relations = true
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
daos = false
pojosEqualsAndHashCode = true
javaTimeTypes = true
target
packageName = 'de.project.service.jooq'
database
name = 'org.jooq.meta.extensions.ddl.DDLDatabase'
properties
property
key = 'scripts'
value = 'src/main/resources/db/migration/*.sql'
property
key = 'sort'
value = 'semantic'
property
key = 'unqualifiedSchema'
value = 'none'
property
key = 'defaultNameCase'
value = 'lower'
【问题讨论】:
您可以尝试在 drop view 之前添加 -- [jooq ignore start] 并在之后添加 -- [jooq ignore stop] 吗? 感谢您的评论。忽略视图确实有助于避免错误。然而,我希望有一个可以从视图中处理 sql 的解决方案。毕竟这适用于以前的 jooq 版本。 完整的堆栈跟踪和代码生成配置是什么? 我更新了问题并添加了stacktrace和更新到jooq版本3.15.5后的配置 感谢您的更新。为了完整起见,您能否在省略号 (...
) 的位置添加您省略的内容。是coalesce
还是"coalesce"
?如果是后者,这可能是github.com/jOOQ/jOOQ/issues/11342 的情况
【参考方案1】:
您可能有以下配置集:
<property>
<key>defaultNameCase</key>
<value>lower</value>
</property>
在 jOOQ 3.15 中,这会将所有标识符转换为小写并引用它们,然后再将 SQL 语句交给 H2 以进行 DDL 模拟,以模拟例如PostgreSQL 行为,其中不带引号的标识符是小写的,而不是许多其他 RDBMS 中的大写。
当前实现中有一个错误,它还引用了内置函数,而不仅仅是用户定义的对象。见:
https://github.com/jOOQ/jOOQ/issues/9931(与“系统名称”相关的一般问题) https://github.com/jOOQ/jOOQ/issues/12752(DDLDatabase
具体问题)
我能想到的唯一解决方法是再次关闭该属性,并手动将所有标识符引用为小写。或者,您可以随时连接到实际数据库,而不是使用DDLDatabase
,例如by using testcontainers。无论如何,这在很多方面都会比DDLDatabase
更强大
无论如何,这是一个非常常见的问题,所以,我已经为即将到来的 jOOQ 3.16 解决了这个问题。上述设置将不再引用“系统名称”,这是众所周知的内置函数标识符
【讨论】:
以上是关于使用 DDL 数据库生成代码时找不到函数 - jooq的主要内容,如果未能解决你的问题,请参考以下文章
ActiveRecord 将在迁移时创建数据库,但当我尝试保存某些内容或生成架构时找不到它