Jooq- 将字段更新为 NULL 使其成为 "null" 而不是 NULL
Jooq- Updating a field to NULL makes it "null" and not NULL
所以这是我以前在 jooq 3.11 中工作的查询。
我正在更新一个 JSON 字段,但是它使用 JsonBinding 映射到我的模型中的一个字符串,我将在下面 post
dsl.update(TASK)
.set(TASK.JSON_SOLUTION, (String) null).
.where(TASK.TENANT.eq(getCurrentTenant()))
.and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()
升级到 jooq 3.13.2 后现在不再有效。我还必须将我的 sql 方言更改为 mysql,即使我正在使用 mysql 5_7 数据库,这可能是问题所在?
这个我也试过了,还是一样
dsl.update(TASK)
.setNull(TASK.JSON_SOLUTION).
.where(TASK.TENANT.eq(getCurrentTenant()))
.and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()
JsonBinding.class
public class JsonBinding implements Binding<JSON, String> {
@Override
public Converter<JSON, String> converter() {
return new JsonConverter();
}
@Override
public void sql(BindingSQLContext<String> bindingSQLContext) {
if (bindingSQLContext.render().paramType() == ParamType.INLINED) {
bindingSQLContext
.render()
.visit(DSL.inline(bindingSQLContext.convert(converter()).value()))
.sql("::json");
} else {
bindingSQLContext.render().sql("?");
}
}
@Override
public void register(BindingRegisterContext<String> bindingRegisterContext) throws SQLException {
bindingRegisterContext
.statement()
.registerOutParameter(bindingRegisterContext.index(), Types.VARCHAR);
}
@Override
public void set(BindingSetStatementContext<String> bindingSetStatementContext)
throws SQLException {
bindingSetStatementContext
.statement()
.setString(
bindingSetStatementContext.index(),
Objects.toString(bindingSetStatementContext.convert(converter()).value(), null));
}
@Override
public void set(BindingSetSQLOutputContext<String> bindingSetSQLOutputContext)
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void get(BindingGetResultSetContext<String> bindingGetResultSetContext)
throws SQLException {
bindingGetResultSetContext
.convert(converter())
.value(
JSON.valueOf(
bindingGetResultSetContext
.resultSet()
.getString(bindingGetResultSetContext.index())));
}
@Override
public void get(BindingGetStatementContext<String> bindingGetStatementContext)
throws SQLException {
bindingGetStatementContext
.convert(converter())
.value(
JSON.valueOf(
bindingGetStatementContext
.statement()
.getString(bindingGetStatementContext.index())));
}
@Override
public void get(BindingGetSQLInputContext<String> bindingGetSQLInputContext) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
}
JsonConverter.class
public class JsonConverter implements Converter<JSON, String> {
@Override
public String from(JSON object) {
return object != null ? object.toString() : null;
}
@Override
public JSON to(String string) {
return JSON.valueOf(string);
}
@Override
public Class<JSON> fromType() {
return JSON.class;
}
@Override
public Class<String> toType() {
return String.class;
}
}
这是使用 .setNull()
运行的查询 jooq
update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = 'null'::json where (`tasks_service`.`task`.`tenant` = 'skynet' and `tasks_service`.`task`.`task_template_id` in ('55', '33'))
在 jooq 3.11 升级之前,查询结果如下
update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = null::json where (`tasks_service`.`task`.`tenant` = 'skynet' and `tasks_service`.`task`.`task_template_id` in ('55', '33'))
所以在设置 'json_solution' = null 之前和升级之后它似乎设置为 'json_solution' = 'null'
不太清楚为什么会这样?
编辑:据我所知,这似乎完全来自 JOOQ 的升级,而不是 sql-方言。使用 Jooq 3.11.5,同时使用 mysql 和 mysql_5_7 作为方言,如果我将 JOOQ 升级到 3.13.2,查询将构建为 set 'json_solution' = null它的集合 'json_solution' = 'null'
这个怪癖似乎也只发生在 JSON 字段上,我尝试在同一个 table 上将另一个 varchar String 字段设置为 null,我得到了正确的设置“field_name' = null
问题可能出在我的 JsonBinding/JsonConverter 上?我不得不稍微修改它以使用 JOOQ 中的新 JSON 对象,因为之前 JOOQ 将 JSON 映射为 Object
JSON.valueOf(null)
对比 (JSON) null
答案在org.jooq.JSON
的Javadoc中:
A CAST(NULL AS JSON)
value is represented by a null
reference of type JSON
, not as data() == null
. This is consistent with jOOQ's general way of returning NULL
from Result
and Record
methods.
所以,错误在于JsonConverter
对JSON.valueOf()
的用法。改为这样写:
public JSON to(String string) {
return string == null ? null : JSON.valueOf(string);
}
或者,只需使用 Converter.ofNullable()
,它会为您处理 null-to-null 映射:
Converter<JSON, String> converter = Converter.ofNullable(
JSON.class,
String.class,
JSON::data,
JSON::json
);
关于使用 Binding
的附注
你真的不再需要绑定了,现在 jOOQ 原生支持 JSON
类型。如果您想将 JSON
转换为 String
,您的 Converter
就足够了。
所以这是我以前在 jooq 3.11 中工作的查询。
我正在更新一个 JSON 字段,但是它使用 JsonBinding 映射到我的模型中的一个字符串,我将在下面 post
dsl.update(TASK)
.set(TASK.JSON_SOLUTION, (String) null).
.where(TASK.TENANT.eq(getCurrentTenant()))
.and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()
升级到 jooq 3.13.2 后现在不再有效。我还必须将我的 sql 方言更改为 mysql,即使我正在使用 mysql 5_7 数据库,这可能是问题所在?
这个我也试过了,还是一样
dsl.update(TASK)
.setNull(TASK.JSON_SOLUTION).
.where(TASK.TENANT.eq(getCurrentTenant()))
.and(TASK.TASK_TEMPLATE_ID.in(taskTemplateIds));execute()
JsonBinding.class
public class JsonBinding implements Binding<JSON, String> {
@Override
public Converter<JSON, String> converter() {
return new JsonConverter();
}
@Override
public void sql(BindingSQLContext<String> bindingSQLContext) {
if (bindingSQLContext.render().paramType() == ParamType.INLINED) {
bindingSQLContext
.render()
.visit(DSL.inline(bindingSQLContext.convert(converter()).value()))
.sql("::json");
} else {
bindingSQLContext.render().sql("?");
}
}
@Override
public void register(BindingRegisterContext<String> bindingRegisterContext) throws SQLException {
bindingRegisterContext
.statement()
.registerOutParameter(bindingRegisterContext.index(), Types.VARCHAR);
}
@Override
public void set(BindingSetStatementContext<String> bindingSetStatementContext)
throws SQLException {
bindingSetStatementContext
.statement()
.setString(
bindingSetStatementContext.index(),
Objects.toString(bindingSetStatementContext.convert(converter()).value(), null));
}
@Override
public void set(BindingSetSQLOutputContext<String> bindingSetSQLOutputContext)
throws SQLException {
throw new SQLFeatureNotSupportedException();
}
@Override
public void get(BindingGetResultSetContext<String> bindingGetResultSetContext)
throws SQLException {
bindingGetResultSetContext
.convert(converter())
.value(
JSON.valueOf(
bindingGetResultSetContext
.resultSet()
.getString(bindingGetResultSetContext.index())));
}
@Override
public void get(BindingGetStatementContext<String> bindingGetStatementContext)
throws SQLException {
bindingGetStatementContext
.convert(converter())
.value(
JSON.valueOf(
bindingGetStatementContext
.statement()
.getString(bindingGetStatementContext.index())));
}
@Override
public void get(BindingGetSQLInputContext<String> bindingGetSQLInputContext) throws SQLException {
throw new SQLFeatureNotSupportedException();
}
}
JsonConverter.class
public class JsonConverter implements Converter<JSON, String> {
@Override
public String from(JSON object) {
return object != null ? object.toString() : null;
}
@Override
public JSON to(String string) {
return JSON.valueOf(string);
}
@Override
public Class<JSON> fromType() {
return JSON.class;
}
@Override
public Class<String> toType() {
return String.class;
}
}
这是使用 .setNull()
运行的查询 jooqupdate `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = 'null'::json where (`tasks_service`.`task`.`tenant` = 'skynet' and `tasks_service`.`task`.`task_template_id` in ('55', '33'))
在 jooq 3.11 升级之前,查询结果如下
update `tasks_service`.`task` set `tasks_service`.`task`.`json_solution` = null::json where (`tasks_service`.`task`.`tenant` = 'skynet' and `tasks_service`.`task`.`task_template_id` in ('55', '33'))
所以在设置 'json_solution' = null 之前和升级之后它似乎设置为 'json_solution' = 'null'
不太清楚为什么会这样?
编辑:据我所知,这似乎完全来自 JOOQ 的升级,而不是 sql-方言。使用 Jooq 3.11.5,同时使用 mysql 和 mysql_5_7 作为方言,如果我将 JOOQ 升级到 3.13.2,查询将构建为 set 'json_solution' = null它的集合 'json_solution' = 'null'
这个怪癖似乎也只发生在 JSON 字段上,我尝试在同一个 table 上将另一个 varchar String 字段设置为 null,我得到了正确的设置“field_name' = null
问题可能出在我的 JsonBinding/JsonConverter 上?我不得不稍微修改它以使用 JOOQ 中的新 JSON 对象,因为之前 JOOQ 将 JSON 映射为 Object
JSON.valueOf(null)
对比 (JSON) null
答案在org.jooq.JSON
的Javadoc中:
A
CAST(NULL AS JSON)
value is represented by anull
reference of typeJSON
, not asdata() == null
. This is consistent with jOOQ's general way of returningNULL
fromResult
andRecord
methods.
所以,错误在于JsonConverter
对JSON.valueOf()
的用法。改为这样写:
public JSON to(String string) {
return string == null ? null : JSON.valueOf(string);
}
或者,只需使用 Converter.ofNullable()
,它会为您处理 null-to-null 映射:
Converter<JSON, String> converter = Converter.ofNullable(
JSON.class,
String.class,
JSON::data,
JSON::json
);
关于使用 Binding
的附注
你真的不再需要绑定了,现在 jOOQ 原生支持 JSON
类型。如果您想将 JSON
转换为 String
,您的 Converter
就足够了。