我遇到了与自定义转换器和String值有关的问题。
设置:
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
无法正确处理此问题,因为final String s
方法中的参数from
为空,这会导致意外行为
编辑:Stacktrace:
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)
答案 0 :(得分:1)
这是jOOQ中的错误:https://github.com/jOOQ/jOOQ/issues/7742
jOOQ使用null
参数调用转换器的原因是因为在多行INSERT
语句中,每行没有设置相同的列,因此需要每行缺少的列的占位符绑定值。示例:
dslContext.insertInto(SOME_TABLE)
.set(SOME_TABLE.SOME_OBJECT, new SomeObject("string"))
.newRecord()
.set(SOME_TABLE.SOME_OTHER_OBJECT, "other")
.execute();
在上述情况下,第二行需要为null
列产生一个SOME_OBJECT
值,以使insert语句在语法上正确。
当然,就您而言,这不适用。 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();
}
...
}