Postgresql 从select提取时的jOOQ和StackOverflowException

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.&

我使用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.<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
。它内部有一个类型。 在class
DefaultBinding
中执行的步骤包括:

  • 方法
    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;
        }
    }