jooq 在极少数情况下生成的 sql 不正确
Incorrect sql generated by jooq on rare occasions
我有一个 spring 云网关应用程序将身份验证数据保存到数据库。应用程序在 kubernetes 中运行。我有太多不同的情况,有时我有 json 数据要保存,而其他时候 json 数据为空。保存此数据的代码如下所示:
with(AUTHENTICATED_SESSION) {
context.insertInto(this, ACCESS_TOKEN_MD5_HASH, REFRESH_TOKEN, CONTEXT_DATA)
.values(
accessTokenMd5,
refreshToken,
if (contextData != null) {
JSONB.jsonb(objectMapper.writeValueAsString(contextData))
} else {
null
}
)
.execute()
}
生成列定义
public final TableField<AuthenticatedSessionRecord, JSONB> CONTEXT_DATA = createField(DSL.name("context_data"), SQLDataType.JSONB, this, "");
保存空值通常会像它应该的那样工作:
insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values (?, ?, cast(? as jsonb))
: -> with bind values : insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values ('hash', 'token', cast(null as jsonb))
有时查询看起来像这样,它会导致下面的异常
insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values (?, ?, ?)
: -> with bind values : insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values ('hash', 'token', null)
org.jooq.exception.DataAccessException: SQL [insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values (?, ?, ?)]; ERROR: column "context_data" is of type jsonb but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 121
at org.jooq_3.14.6.DEFAULT.debug(Unknown Source) ~[na:na]
at org.jooq.impl.Tools.translate(Tools.java:2880) ~[jooq-3.14.6.jar:na]
at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:757) ~[jooq-3.14.6.jar:na]
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:389) ~[jooq-3.14.6.jar:na]
at org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:119) ~[jooq-3.14.6.jar:na]
所以在极少数情况下,jooq 似乎会生成不正确的 sql(没有强制转换为 jsonb)。
这个问题真的很烦人,因为发生这种情况时应用程序根本无法使用。重新启动吊舱有帮助。这个问题很可能只有在应用程序启动后才会出现。
使用的版本:
- jooq 3.14.6
- spring 引导 2.3.5.RELEASE
- spring云网关2.2.5.RELEASE
- Postgresql docker 容器中的 10.12
- postgresql 驱动程序 42.2.5
- 科特林 1.4.10
你的问题中有提示,每次看到它,我都很高兴实现了这个功能:
at org.jooq_3.14.6.DEFAULT.debug(Unknown Source) ~[na:na]
DEFAULT
在您的案例中指的是 SQLDialect.DEFAULT
, but it should be SQLDialect.POSTGRES
。你变得无效的原因 SQL 是因为在那些情况下,你没有正确配置 Configuration
.
这应该可以帮助您找到问题所在,请记住 jOOQ Query
对象不是线程安全的。
我有一个 spring 云网关应用程序将身份验证数据保存到数据库。应用程序在 kubernetes 中运行。我有太多不同的情况,有时我有 json 数据要保存,而其他时候 json 数据为空。保存此数据的代码如下所示:
with(AUTHENTICATED_SESSION) {
context.insertInto(this, ACCESS_TOKEN_MD5_HASH, REFRESH_TOKEN, CONTEXT_DATA)
.values(
accessTokenMd5,
refreshToken,
if (contextData != null) {
JSONB.jsonb(objectMapper.writeValueAsString(contextData))
} else {
null
}
)
.execute()
}
生成列定义
public final TableField<AuthenticatedSessionRecord, JSONB> CONTEXT_DATA = createField(DSL.name("context_data"), SQLDataType.JSONB, this, "");
保存空值通常会像它应该的那样工作:
insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values (?, ?, cast(? as jsonb))
: -> with bind values : insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values ('hash', 'token', cast(null as jsonb))
有时查询看起来像这样,它会导致下面的异常
insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values (?, ?, ?)
: -> with bind values : insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values ('hash', 'token', null)
org.jooq.exception.DataAccessException: SQL [insert into "public"."authenticated_session" ("access_token_md5_hash", "refresh_token", "context_data") values (?, ?, ?)]; ERROR: column "context_data" is of type jsonb but expression is of type character varying
Hint: You will need to rewrite or cast the expression.
Position: 121
at org.jooq_3.14.6.DEFAULT.debug(Unknown Source) ~[na:na]
at org.jooq.impl.Tools.translate(Tools.java:2880) ~[jooq-3.14.6.jar:na]
at org.jooq.impl.DefaultExecuteContext.sqlException(DefaultExecuteContext.java:757) ~[jooq-3.14.6.jar:na]
at org.jooq.impl.AbstractQuery.execute(AbstractQuery.java:389) ~[jooq-3.14.6.jar:na]
at org.jooq.impl.AbstractDelegatingQuery.execute(AbstractDelegatingQuery.java:119) ~[jooq-3.14.6.jar:na]
所以在极少数情况下,jooq 似乎会生成不正确的 sql(没有强制转换为 jsonb)。
这个问题真的很烦人,因为发生这种情况时应用程序根本无法使用。重新启动吊舱有帮助。这个问题很可能只有在应用程序启动后才会出现。
使用的版本:
- jooq 3.14.6
- spring 引导 2.3.5.RELEASE
- spring云网关2.2.5.RELEASE
- Postgresql docker 容器中的 10.12
- postgresql 驱动程序 42.2.5
- 科特林 1.4.10
你的问题中有提示,每次看到它,我都很高兴实现了这个功能:
at org.jooq_3.14.6.DEFAULT.debug(Unknown Source) ~[na:na]
DEFAULT
在您的案例中指的是 SQLDialect.DEFAULT
, but it should be SQLDialect.POSTGRES
。你变得无效的原因 SQL 是因为在那些情况下,你没有正确配置 Configuration
.
这应该可以帮助您找到问题所在,请记住 jOOQ Query
对象不是线程安全的。