PostgreSQL下jOOQ元模型无法生成OffsetDateTime类型问题
技术栈
- Jooq 3.16.10
- Java 11
- Spring Boot 2.6.7
- PostgreSQL 14
- jOOQ Maven插件
DDL定义
CREATE TABLE IF NOT EXISTS table ( .... "id" uuid, "created_datetime" TIMESTAMP WITH TIME ZONE, .... );
jOOQ Maven插件完整配置
<plugin> <groupId>org.jooq</groupId> <artifactId>jooq-codegen-maven</artifactId> <version>3.16.10</version> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>com.amazonaws.secretsmanager</groupId> <artifactId>aws-secretsmanager-jdbc</artifactId> <version>1.0.8</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.3.3</version> </dependency> </dependencies> <configuration> <jdbc> ..... </jdbc> <generator> <name>org.jooq.codegen.KotlinGenerator</name> <generate> <pojosAsKotlinDataClasses>true</pojosAsKotlinDataClasses> <javaTimeTypes>true</javaTimeTypes> </generate> <database> <name>org.jooq.meta.postgres.PostgresDatabase</name> <includes>MYTABLE</includes> <inputSchema>public</inputSchema> </database> <target> <packageName>tech.ringieraxelspringer.enrichmentapi.infrastructure.job.rds.jooq</packageName> <directory>${project.basedir}/src/main/java</directory> </target> </generator> </configuration> </plugin>
问题描述
配置了<javaTimeTypes>true</javaTimeTypes>,期望PostgreSQL的TIMESTAMP WITH TIME ZONE字段在生成的jOOQ元模型中对应OffsetDateTime类型,但实际生成的是LocalDateTime,请问问题出在哪里?
排查方向与解决方案
1. 确认数据库字段真实类型
先查数据库里created_datetime的实际类型是不是TIMESTAMP WITH TIME ZONE(PostgreSQL里别名是timestamptz),别不小心建了普通TIMESTAMP(timestamp)。执行以下SQL验证:
SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'table' AND column_name = 'created_datetime';
如果结果是timestamp,那生成LocalDateTime是正常的,得改DDL重新建表。
2. KotlinGenerator的默认映射规则
在jOOQ 3.16.x版本中,当开启<pojosAsKotlinDataClasses>true</pojosAsKotlinDataClasses>时,KotlinGenerator会默认把timestamptz映射成LocalDateTime——这是当时为了兼容Kotlin序列化框架(对OffsetDateTime支持不够友好)做的妥协,和<javaTimeTypes>配置不冲突但会覆盖部分行为。
要强制映射为OffsetDateTime,需要在<database>节点下加自定义类型映射:
<forcedTypes> <forcedType> <userType>java.time.OffsetDateTime</userType> <includeTypes>timestamptz</includeTypes> <!-- 可选:只针对created_datetime字段,去掉则全局映射所有timestamptz --> <includeExpression>created_datetime</includeExpression> </forcedType> </forcedTypes>
3. 检查JDBC驱动兼容性
虽然当前用的PostgreSQL驱动42.3.3和jOOQ 3.16.10理论兼容,但可以尝试升级驱动到同系列最新版(比如42.5.4),避免驱动返回类型异常导致jOOQ识别错误。
4. 清理并重新生成代码
执行mvn clean jooq-codegen:generate,确保旧的生成代码被彻底清理,基于最新配置和数据库元数据重新生成。
内容的提问来源于stack exchange,提问作者user6595600

