已部署Flyway迁移文件标识符未正确引号致jOOQ代码生成错误的解决方法
解决jOOQ代码生成因Flyway迁移标识符引号不一致的问题
问题背景
生产环境已执行v0.0.5的Flyway迁移(未给表名/列名加引号),后续开发环境添加v0.0.6表结构变更迁移后,运行jOOQ代码生成时,DDLDatabase解析v0.0.5的SQL时将未引号的标识符转为大写,导致找不到实际小写的pricing_plan表,抛出解析错误。
可行解决方案
方案1:修正开发环境迁移文件并同步Flyway执行状态
- 将开发环境中
V0_0_5__xxx.sql的SQL替换为带引号的正确版本:INSERT INTO "pricing_plan" ("name") SELECT unnest(ARRAY['Free', 'Paid', 'Paid with free trial or plan']) EXCEPT SELECT "name" FROM "pricing_plan"; - 若开发环境已执行过原v0.0.5迁移:
- 回滚到v0.0.4版本:
flyway undo -target=0.0.4 - 重新执行所有迁移:
flyway migrate
- 回滚到v0.0.4版本:
- 若开发环境为全新环境,直接执行
flyway migrate即可,此时迁移SQL均符合引号规范,jOOQ代码生成可正常解析。
方案2:调整jOOQ DDLDatabase配置兼容大小写
无需修改历史迁移文件,仅在jOOQ代码生成配置中添加标识符大小写转换规则,让DDLDatabase将未引号的标识符解析为小写(匹配PostgreSQL默认存储行为):
Maven配置示例
<plugin> <groupId>org.jooq</groupId> <artifactId>jooq-codegen-maven</artifactId> <version>3.19.15</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <generator> <database> <name>org.jooq.meta.extensions.ddl.DDLDatabase</name> <properties> <property name="dialect" value="POSTGRES"/> <!-- 将未引号标识符转为小写,匹配PostgreSQL实际表名 --> <property name="unquotedIdentifierCase" value="LOWER"/> </properties> <!-- 指定Flyway迁移文件目录 --> <includes>.*</includes> <inputPaths> <inputPath>src/main/resources/db/migration</inputPath> </inputPaths> </database> <!-- 其他代码生成配置(目标包、目录等) --> </generator> </configuration> </plugin>
Gradle配置示例
jooq { version = '3.19.15' edition = org.jooq.meta.jaxb.Edition.COMMUNITY generateSchemaSourceOnCompilation = true configurations { main { jooqConfiguration { generator { database { name = 'org.jooq.meta.extensions.ddl.DDLDatabase' properties { property { key = 'dialect' value = 'POSTGRES' } property { key = 'unquotedIdentifierCase' value = 'LOWER' } } includes = '.*' inputPaths = ['src/main/resources/db/migration'] } // 其他代码生成配置 } } } } }
添加该配置后,DDLDatabase会将v0.0.5中未引号的pricing_plan解析为小写,与实际表名匹配,避免找不到表的错误。
方案3:添加Flyway可重复迁移补充修正
新增一个可重复迁移文件(命名格式为R__Fix_Pricing_Plan_Identifier_Quotes.sql),执行幂等性的插入操作(确保数据一致):
-- 确保标识符带引号,兼容大小写敏感场景 INSERT INTO "pricing_plan" ("name") SELECT unnest(ARRAY['Free', 'Paid', 'Paid with free trial or plan']) EXCEPT SELECT "name" FROM "pricing_plan";
该迁移会在每次flyway migrate时执行,保证数据一致性,同时配合方案2的jOOQ配置,可彻底解决标识符解析问题。
内容的提问来源于stack exchange,提问作者mw222
相关产品推荐
相关产品推荐

