我尝试更新Postgres daterange
。无论我尝试什么,它都不起作用。目前我得到
错误:(51,17)java:对set的引用是不明确的 org.jooq.UpdateSetStep中的方法集(org.jooq.Field,T)和org.jooq.UpdateSetStep中的方法集(org.jooq.Field,org.jooq.Field)匹配
这是我的代码
ctx.update(AT_PREFERENCS)
.set(AT_PREFERENCS.DIRECTION, preferences.direction)
.set(AT_PREFERENCS.START_END, (Field<Object>) DSL.field("daterange(?, ?)", Object.class, preferences.start, preferences.end))
.where(AT_PREFERENCS.USER.eq(userId))
.execute();
如何使用jOOQ更新daterange
?
答案 0 :(得分:2)
这是由于非常不幸的Java语言设计问题(我认为是一个重大缺陷)documented in this question here。 jOOQ应该解决这个问题,但鉴于jOOQ早于Java 8并且Java 8中引入了语言设计回归,现在无法在jOOQ API中轻松地向后兼容地修复它。
有几种解决方法:
如果您计划更频繁地使用此范围类型,这可能是最强大的解决方案,如果您应该定义custom data type binding。它预先做了一些额外的工作,但是一旦你有了这个指定,你就可以写下:
.set(AT_PREFERENCES.START_END, new MyRangeType(preferences.start, preferences.end))
其中AT_PREFERENCES.START_END
为Field<MyRangeType>
。
Object
如果您只使用此类型一次或两次,这是一种快速解决方法。它对运行时没有影响,只需调整编译器就相信这是正确的。
.<Void>set(
(Field) AT_PREFERENCES.START_END,
(Field) DSL.field("daterange(?, ?)", Object.class, preferences.start, preferences.end))
Field<T>
类型与之前相同,但是这样,类型推断可以为<Void>
推断<T>
.set(
(Field<Void>) (Field) AT_PREFERENCES.START_END,
(Field<Void>) (Field) DSL.field("daterange(?, ?)", Object.class,
preferences.start, preferences.end))
jOOQ内部处理所有方法调用,在极少数情况下,类型安全性中断并且&#34;错误&#34;调用过载。所以,您也可以简单地称之为:
.set(
AT_PREFERENCES.START_END,
(Object) DSL.field("daterange(?, ?)", Object.class,
preferences.start, preferences.end))
使用此强制转换,只有set(Field<T>, T)
方法适用,并且您不再依赖Java编译器在适用的重载(which no longer works since Java 8)中找到最具体的方法。
jOOQ将对instanceof
参数运行T
检查,看看它是否真的是Field
类型,如果它在内部重新路由到预期的API方法set(Field<T>, Field<T>)