我遇到了与自定义转换器和字符串值相关的问题。
设置:
JOOQ 版本 - 3.11.0
maven 插件中的forcedTypes 部分:
<forcedType>
<userType>com.test.SomeObject</userType>
<converter>com.test.SomeObjectConverter</converter>
<expression>some_object</expression>
<types>.*</types>
</forcedType>
some_object sql 定义:
some_object character varying(255) NOT NULL
转换器本身:
public class SomeObjectConverter implements Converter<String, SomeObject> {
@Override
public SomeObject from(final String s) {
return new SomeObject(s);
}
@Override
public String to(final SomeObject someObject) {
return someObject.getFieldsThatsString();
}
@Override
public Class<String> fromType() {
return String.class;
}
@Override
public Class<SomeObject> toType() {
return SomeObject.class;
}
}
生成的 JOOQ 记录中的字段类型正确
public final TableField<SomeTableRecord, SomeObject> SOME_OBJECT
不幸的是,当我执行查询时
dslContext.insertInto(SOME_TABLE)
.set(SOME_TABLE.SOME_OBJECT, new SomeObject("string")).execute();
SomeObjectConverter
无法正确处理此问题,因为 from
方法中的参数 final String s
为 null,这会导致意外行为
编辑:堆栈跟踪:
java.lang.NullPointerException
at com.test.SomeObject.<init>(SomeObject.java:16)
at com.test.SomeObjectConverter.from(HierarchyIdConverter.java:10)
at com.test.SomeObjectConverter.from(HierarchyIdConverter.java:6)
at org.jooq.impl.ConvertedDataType.convert(ConvertedDataType.java:105)
at org.jooq.impl.DSL.val(DSL.java:19800)
at org.jooq.impl.DSL.val(DSL.java:19769)
at org.jooq.impl.FieldMapsForInsert.addFields(FieldMapsForInsert.java:287)
at org.jooq.impl.FieldMapsForInsert.set(FieldMapsForInsert.java:315)
at org.jooq.impl.FieldMapsForInsert$2.put(FieldMapsForInsert.java:402)
at org.jooq.impl.FieldMapsForInsert$2.put(FieldMapsForInsert.java:368)
at org.jooq.impl.AbstractStoreQuery.addValue(AbstractStoreQuery.java:85)
at org.jooq.impl.InsertImpl.set(InsertImpl.java:688)
at org.jooq.impl.InsertImpl.set(InsertImpl.java:126)
at com.test.Repository.insertSomeObject(Repository.java:26)
最佳答案
这是 jOOQ 中的一个错误:https://github.com/jOOQ/jOOQ/issues/7742
jOOQ 使用 null
参数调用转换器的原因是,在多行 INSERT
语句的情况下,不会在每行上设置相同的列,每行上缺少的列需要有一个占位符绑定(bind)值。示例:
dslContext.insertInto(SOME_TABLE)
.set(SOME_TABLE.SOME_OBJECT, new SomeObject("string"))
.newRecord()
.set(SOME_TABLE.SOME_OTHER_OBJECT, "other")
.execute();
在上述情况下,第二行需要为 SOME_OBJECT
列生成 null
值,以便插入语句在语法上正确。
当然,就您而言,这不应该适用。 null
值初始化应该在 jOOQ 内部更加延迟地实现。
解决方法
使您的转换器null
安全,例如:
public class SomeObjectConverter implements Converter<String, SomeObject> {
@Override
public SomeObject from(final String s) {
return s == null ? null : new SomeObject(s);
}
@Override
public String to(final SomeObject s) {
return s == null ? null : s.getFieldsThatsString();
}
...
}
关于java - 字符变化列的自定义转换器 - from 方法中的参数为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51769846/