Postgresql 从select提取时的jOOQ和StackOverflowException
我使用jOOQ 3.8.4和Postgres 9.5。 我有一个复杂的模式。实际上,当我做一个简单的选择时,比如:Postgresql 从select提取时的jOOQ和StackOverflowException,postgresql,stack-overflow,jooq,Postgresql,Stack Overflow,Jooq,我使用jOOQ 3.8.4和Postgres 9.5。 我有一个复杂的模式。实际上,当我做一个简单的选择时,比如: create.selectFrom(ARTICLE_VIEW) .orderBy(ARTICLE_VIEW.AV_CREATION_DATE .desc()).limit(4).fetch(); 我得到: java.lang.StackOverflowError org.jooq.Converters$1.&
create.selectFrom(ARTICLE_VIEW)
.orderBy(ARTICLE_VIEW.AV_CREATION_DATE
.desc()).limit(4).fetch();
我得到:
java.lang.StackOverflowError
org.jooq.Converters$1.<init>(Converters.java:67)
org.jooq.Converters.identity(Converters.java:67)
org.jooq.impl.DefaultBinding.pgFromString(DefaultBinding.java:2041)
org.jooq.impl.DefaultBinding.pgFromString(DefaultBinding.java:2130)
org.jooq.impl.DefaultBinding.pgFromString(DefaultBinding.java:2041)
org.jooq.impl.DefaultBinding.pgFromString(DefaultBinding.java:2130)
org.jooq.impl.DefaultBinding.pgFromString(DefaultBinding.java:2041)
问题的可能来源 我根据来自的链接进行了调试,但问题似乎出在jOOQ中。它不能正确处理类型内部的类型 该视图包含一个PostgreSQL类型的
ArticleSimpleTypeRecord
。它内部有一个类型。
在classDefaultBinding
中执行的步骤包括:
pgFromString
通过ArticleSimpleTypeRecord
的默认转换器调用。这意味着调用以下指令:
else if(Record.class.isAssignableFrom(type)){
return(T)pgNewRecord(type,null,string);
}pgNewRecord
尝试通过调用以下方法从给定对象创建记录:
public Record operate(Record record) {
List<String> values = PostgresUtils.toPGObject(object.toString());
Row row = record.fieldsRow();
for (int i = 0; i < row.size(); i++) {
pgSetValue(record, row.field(i), values.get(i));
}
return record;
}
问题来了,因为json转换器应该将值转换为json,从pgFromString(c.fromType(),string)
返回的对象开始,但是从c.fromType()开始
返回对象
并且jOOQ中没有对象的默认绑定,它一次又一次地转到默认情况,我们有堆栈溢出异常
else if (type == Object.class) {
return (T) string;
}
然后,我必须等待下一个jOOQ小版本。我希望它很快就会到来。您为JsonElement注册了自定义绑定吗?我们也使用Gson类型,并且必须执行以下操作: pom.xml(缩写)
org.jooq
jooq codegen maven
${jooq.version}
GsonJson
com.google.gson.JsonElement
com.mycompany.dao.bindings.GsonJsonBinding
json
GsonJsonBinding.java
public class GsonJsonBinding extends GenericStringlikeBinding<JsonElement> {
public GsonJsonBinding() {
super("json", new JsonConverter());
}
}
公共类GsonJsonBinding扩展了GenericStringlikeBinding{
公共GsonJsonBinding(){
超级(“json”,新的JsonConverter());
}
}
JsonConverter.java
public class JsonConverter implements Converter<Object, JsonElement> {
private static final Gson gson = new Gson();
@Override
public JsonElement from(Object t) {
return t == null ? null : gson.fromJson("" + t, JsonElement.class);
}
@Override
public Object to(JsonElement u) {
return u == null || u == JsonNull.INSTANCE ? null : gson.toJson(u);
}
@Override
public Class<Object> fromType() {
return Object.class;
}
@Override
public Class<JsonElement> toType() {
return JsonElement.class;
}
}
公共类JsonConverter实现转换器{
私有静态最终Gson Gson=new Gson();
@凌驾
来自(对象t)的公共JsonElement{
返回t==null?null:gson.fromJson(“+t,jsoneElement.class”);
}
@凌驾
公共对象到(JsonElement u){
返回u==null | | u==JsonNull.INSTANCE?null:gson.toJson(u);
}
@凌驾
公共类fromType(){
返回Object.class;
}
@凌驾
公共类toType(){
返回JsonElement.class;
}
}
您是如何生成记录类的?(发布ArticleViewRecord
可能会有所帮助。)在ARTICLE\u VIEW
中,似乎有一个类型试图从字符串反序列化为非标准类型,它陷入了无限循环@AndrewRueckert记录类已发布。所以,我也怀疑这一点。视野很好,选择也不错。我知道将一些json替换为PostgreSQL类型,这应该是问题所在。我只是想知道如何调试这个。stacktrace没有帮助。我编译了版本3.9.0-SNAPSHOT,不幸的是,它有另一个错误:没有StackOverflowException,但它将内部类型的所有值设置为null,即使它们不是。我发现了null值的问题。Jooq 1.3.9-SNAPSHOT很好地返回记录,还包括所包含类型的记录。当我执行fetch().into(ArticleView.class)
时会出现问题,其中ArticleView.class
是一个pojot。要解决此问题,您可以使用一个自定义,该自定义可能可以通过注册。这是额外的工作,但它应该工作得很好!
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${jooq.version}</version>
<configuration>
<generator>
<database>
<forcedTypes>
<forcedType>
<name>GsonJson</name>
<userType>com.google.gson.JsonElement</userType>
<binding>com.mycompany.dao.bindings.GsonJsonBinding</binding>
<types>json</types>
</forcedType>
</forcedTypes>
</database>
</generator>
</configuration>
</plugin>
public class GsonJsonBinding extends GenericStringlikeBinding<JsonElement> {
public GsonJsonBinding() {
super("json", new JsonConverter());
}
}
public class JsonConverter implements Converter<Object, JsonElement> {
private static final Gson gson = new Gson();
@Override
public JsonElement from(Object t) {
return t == null ? null : gson.fromJson("" + t, JsonElement.class);
}
@Override
public Object to(JsonElement u) {
return u == null || u == JsonNull.INSTANCE ? null : gson.toJson(u);
}
@Override
public Class<Object> fromType() {
return Object.class;
}
@Override
public Class<JsonElement> toType() {
return JsonElement.class;
}
}