使用 jOOQ 更新 Postgres 日期范围
Update a Postgres daterange with jOOQ
我尝试更新 Postgres daterange
。无论我尝试什么都行不通。目前我得到
Error:(51, 17) java: reference to set is ambiguous
both method set(org.jooq.Field,T) in org.jooq.UpdateSetStep and method set(org.jooq.Field,org.jooq.Field) in org.jooq.UpdateSetStep match
这是我的代码
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
?
这是由于非常不幸的 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>
类型
和以前一样,但是这让类型推断完成了为 <T>
推断 <Void>
的工作
.set(
(Field<Void>) (Field) AT_PREFERENCES.START_END,
(Field<Void>) (Field) DSL.field("daterange(?, ?)", Object.class,
preferences.start, preferences.end))
显式绑定到 "wrong" API 方法
jOOQ 在极少数情况下会在内部处理所有方法调用,这些情况会导致类型安全中断并调用 "wrong" 重载。因此,您也可以简单地调用它:
.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 将 运行 对 T
参数进行 instanceof
检查,看它是否真的是 Field
类型,如果它在内部重新通往预期 API 方法的路线 set(Field<T>, Field<T>)
我尝试更新 Postgres daterange
。无论我尝试什么都行不通。目前我得到
Error:(51, 17) java: reference to set is ambiguous both method set(org.jooq.Field,T) in org.jooq.UpdateSetStep and method set(org.jooq.Field,org.jooq.Field) in org.jooq.UpdateSetStep match
这是我的代码
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
?
这是由于非常不幸的 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>
类型
和以前一样,但是这让类型推断完成了为 <T>
<Void>
的工作
.set(
(Field<Void>) (Field) AT_PREFERENCES.START_END,
(Field<Void>) (Field) DSL.field("daterange(?, ?)", Object.class,
preferences.start, preferences.end))
显式绑定到 "wrong" API 方法
jOOQ 在极少数情况下会在内部处理所有方法调用,这些情况会导致类型安全中断并调用 "wrong" 重载。因此,您也可以简单地调用它:
.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 将 运行 对 T
参数进行 instanceof
检查,看它是否真的是 Field
类型,如果它在内部重新通往预期 API 方法的路线 set(Field<T>, Field<T>)