当前位置: 首页 > 知识库问答 >
问题:

从select提取时的jOOQ和StackOverflowException

顾俊哲
2023-03-14

我使用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)

更有趣的是,这是我第一次使用StackOverflowException!

我激活了调试日志记录模式,并在PGAdmin中复制了select和execute命令。它起作用了。jOOQ中应该有一些错误,但我不知道如何提供有用的信息。发布我使用的模式将是疯狂的,它需要几十个表。有关于如何进行的提示吗?

更新

下面是记录类

/**
 * This class is generated by jOOQ
 */
package com.model.jooq.shop.tables.records;


import com.google.gson.JsonElement;

import com.model.jooq.shop.enums.BrandCountry;
import com.model.jooq.shop.enums.Color;
import com.model.jooq.shop.enums.Discount;
import com.model.jooq.shop.enums.Season;
import com.model.jooq.shop.tables.ArticleView;
import com.model.jooq.shop.udt.records.ArticleSimpleTypeRecord;
import com.model.jooq.shop.udt.records.CategoryTypeRecord;
import com.model.jooq.shop.udt.records.LocalizedMoneyRecord;
import com.model.jooq.shop.udt.records.SameModelArticleTypeRecord;

import java.io.Serializable;
import java.sql.Timestamp;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.validation.constraints.Size;

import org.jooq.impl.TableRecordImpl;


/**
 * This class is generated by jOOQ.
 */
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
@Entity
@Table(name = "article_view", schema = "shop")
public class ArticleViewRecord extends TableRecordImpl<ArticleViewRecord> implements Serializable, Cloneable {

    private static final long serialVersionUID = -1404712730;

    /**
     * Setter for <code>shop.article_view.av_article_id</code>.
     */
    public ArticleViewRecord setArticleId(Long value) {
        set(0, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_id</code>.
     */
    @Column(name = "av_article_id", precision = 64)
    public Long getArticleId() {
        return (Long) get(0);
    }

    /**
     * Setter for <code>shop.article_view.av_article_model_id</code>.
     */
    public ArticleViewRecord setArticleModelId(Long value) {
        set(1, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_model_id</code>.
     */
    @Column(name = "av_article_model_id", precision = 64)
    public Long getArticleModelId() {
        return (Long) get(1);
    }

    /**
     * Setter for <code>shop.article_view.av_article_name</code>.
     */
    public ArticleViewRecord setArticleName(String value) {
        set(2, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_name</code>.
     */
    @Column(name = "av_article_name", length = 25)
    @Size(max = 25)
    public String getArticleName() {
        return (String) get(2);
    }

    /**
     * Setter for <code>shop.article_view.av_article_name_for_url</code>.
     */
    public ArticleViewRecord setArticleNameForUrl(String value) {
        set(3, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_name_for_url</code>.
     */
    @Column(name = "av_article_name_for_url", length = 25)
    @Size(max = 25)
    public String getArticleNameForUrl() {
        return (String) get(3);
    }

    /**
     * Setter for <code>shop.article_view.av_article_season</code>.
     */
    public ArticleViewRecord setArticleSeason(Season value) {
        set(4, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_season</code>.
     */
    @Column(name = "av_article_season")
    public Season getArticleSeason() {
        return (Season) get(4);
    }

    /**
     * Setter for <code>shop.article_view.av_article_year</code>.
     */
    public ArticleViewRecord setArticleYear(Short value) {
        set(5, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_year</code>.
     */
    @Column(name = "av_article_year", precision = 16)
    public Short getArticleYear() {
        return (Short) get(5);
    }

    /**
     * Setter for <code>shop.article_view.av_article_standard_size_designation</code>.
     */
    public ArticleViewRecord setArticleStandardSizeDesignation(Boolean value) {
        set(6, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_standard_size_designation</code>.
     */
    @Column(name = "av_article_standard_size_designation")
    public Boolean getArticleStandardSizeDesignation() {
        return (Boolean) get(6);
    }

    /**
     * Setter for <code>shop.article_view.av_article_ean13</code>.
     */
    public ArticleViewRecord setArticleEan13(String value) {
        set(7, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_ean13</code>.
     */
    @Column(name = "av_article_ean13", length = 13)
    @Size(max = 13)
    public String getArticleEan13() {
        return (String) get(7);
    }

    /**
     * Setter for <code>shop.article_view.av_article_config_sku</code>.
     */
    public ArticleViewRecord setArticleConfigSku(String value) {
        set(8, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_config_sku</code>.
     */
    @Column(name = "av_article_config_sku", length = 12)
    @Size(max = 12)
    public String getArticleConfigSku() {
        return (String) get(8);
    }

    /**
     * Setter for <code>shop.article_view.av_article_features</code>.
     */
    public ArticleViewRecord setArticleFeatures(JsonElement value) {
        set(9, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_features</code>.
     */
    @Column(name = "av_article_features")
    public JsonElement getArticleFeatures() {
        return (JsonElement) get(9);
    }

    /**
     * Setter for <code>shop.article_view.av_article_color</code>.
     */
    public ArticleViewRecord setArticleColor(Color value) {
        set(10, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_color</code>.
     */
    @Column(name = "av_article_color")
    public Color getArticleColor() {
        return (Color) get(10);
    }

    /**
     * Setter for <code>shop.article_view.av_article_color2</code>.
     */
    public ArticleViewRecord setArticleColor2(Color value) {
        set(11, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_color2</code>.
     */
    @Column(name = "av_article_color2")
    public Color getArticleColor2() {
        return (Color) get(11);
    }

    /**
     * Setter for <code>shop.article_view.av_article_color3</code>.
     */
    public ArticleViewRecord setArticleColor3(Color value) {
        set(12, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_color3</code>.
     */
    @Column(name = "av_article_color3")
    public Color getArticleColor3() {
        return (Color) get(12);
    }

    /**
     * Setter for <code>shop.article_view.av_article_color_detail</code>.
     */
    public ArticleViewRecord setArticleColorDetail(JsonElement value) {
        set(13, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_color_detail</code>.
     */
    @Column(name = "av_article_color_detail")
    public JsonElement getArticleColorDetail() {
        return (JsonElement) get(13);
    }

    /**
     * Setter for <code>shop.article_view.av_article_paid_price</code>.
     */
    public ArticleViewRecord setArticlePaidPrice(LocalizedMoneyRecord[] value) {
        set(14, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_paid_price</code>.
     */
    @Column(name = "av_article_paid_price")
    public LocalizedMoneyRecord[] getArticlePaidPrice() {
        return (LocalizedMoneyRecord[]) get(14);
    }

    /**
     * Setter for <code>shop.article_view.av_article_price</code>.
     */
    public ArticleViewRecord setArticlePrice(LocalizedMoneyRecord[] value) {
        set(15, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_price</code>.
     */
    @Column(name = "av_article_price")
    public LocalizedMoneyRecord[] getArticlePrice() {
        return (LocalizedMoneyRecord[]) get(15);
    }

    /**
     * Setter for <code>shop.article_view.av_article_image_filenames</code>.
     */
    public ArticleViewRecord setArticleImageFilenames(String[] value) {
        set(16, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_image_filenames</code>.
     */
    @Column(name = "av_article_image_filenames")
    public String[] getArticleImageFilenames() {
        return (String[]) get(16);
    }

    /**
     * Setter for <code>shop.article_view.av_article_active_from</code>.
     */
    public ArticleViewRecord setArticleActiveFrom(Timestamp value) {
        set(17, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_active_from</code>.
     */
    @Column(name = "av_article_active_from")
    public Timestamp getArticleActiveFrom() {
        return (Timestamp) get(17);
    }

    /**
     * Setter for <code>shop.article_view.av_article_discount</code>.
     */
    public ArticleViewRecord setArticleDiscount(Discount value) {
        set(18, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_article_discount</code>.
     */
    @Column(name = "av_article_discount")
    public Discount getArticleDiscount() {
        return (Discount) get(18);
    }

    /**
     * Setter for <code>shop.article_view.av_brand_id</code>.
     */
    public ArticleViewRecord setBrandId(Short value) {
        set(19, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_brand_id</code>.
     */
    @Column(name = "av_brand_id", precision = 16)
    public Short getBrandId() {
        return (Short) get(19);
    }

    /**
     * Setter for <code>shop.article_view.av_brand_name</code>.
     */
    public ArticleViewRecord setBrandName(String value) {
        set(20, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_brand_name</code>.
     */
    @Column(name = "av_brand_name", length = 25)
    @Size(max = 25)
    public String getBrandName() {
        return (String) get(20);
    }

    /**
     * Setter for <code>shop.article_view.av_brand_name_for_url</code>.
     */
    public ArticleViewRecord setBrandNameForUrl(String value) {
        set(21, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_brand_name_for_url</code>.
     */
    @Column(name = "av_brand_name_for_url", length = 25)
    @Size(max = 25)
    public String getBrandNameForUrl() {
        return (String) get(21);
    }

    /**
     * Setter for <code>shop.article_view.av_brand_country</code>.
     */
    public ArticleViewRecord setBrandCountry(BrandCountry value) {
        set(22, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_brand_country</code>.
     */
    @Column(name = "av_brand_country")
    public BrandCountry getBrandCountry() {
        return (BrandCountry) get(22);
    }

    /**
     * Setter for <code>shop.article_view.av_brand_logo_url</code>.
     */
    public ArticleViewRecord setBrandLogoUrl(String value) {
        set(23, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_brand_logo_url</code>.
     */
    @Column(name = "av_brand_logo_url", length = 250)
    @Size(max = 250)
    public String getBrandLogoUrl() {
        return (String) get(23);
    }

    /**
     * Setter for <code>shop.article_view.av_brand_facts</code>.
     */
    public ArticleViewRecord setBrandFacts(JsonElement value) {
        set(24, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_brand_facts</code>.
     */
    @Column(name = "av_brand_facts")
    public JsonElement getBrandFacts() {
        return (JsonElement) get(24);
    }

    /**
     * Setter for <code>shop.article_view.av_commodity_group_id</code>.
     */
    public ArticleViewRecord setCommodityGroupId(Long value) {
        set(25, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_commodity_group_id</code>.
     */
    @Column(name = "av_commodity_group_id", precision = 64)
    public Long getCommodityGroupId() {
        return (Long) get(25);
    }

    /**
     * Setter for <code>shop.article_view.av_commodity_group_name</code>.
     */
    public ArticleViewRecord setCommodityGroupName(String value) {
        set(26, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_commodity_group_name</code>.
     */
    @Column(name = "av_commodity_group_name", length = 25)
    @Size(max = 25)
    public String getCommodityGroupName() {
        return (String) get(26);
    }

    /**
     * Setter for <code>shop.article_view.av_commodity_group_name_for_url</code>.
     */
    public ArticleViewRecord setCommodityGroupNameForUrl(String value) {
        set(27, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_commodity_group_name_for_url</code>.
     */
    @Column(name = "av_commodity_group_name_for_url", length = 25)
    @Size(max = 25)
    public String getCommodityGroupNameForUrl() {
        return (String) get(27);
    }

    /**
     * Setter for <code>shop.article_view.av_categories</code>.
     */
    public ArticleViewRecord setCategories(CategoryTypeRecord[] value) {
        set(28, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_categories</code>.
     */
    @Column(name = "av_categories")
    public CategoryTypeRecord[] getCategories() {
        return (CategoryTypeRecord[]) get(28);
    }

    /**
     * Setter for <code>shop.article_view.av_sizes</code>.
     */
    public ArticleViewRecord setSizes(ArticleSimpleTypeRecord[] value) {
        set(29, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_sizes</code>.
     */
    @Column(name = "av_sizes")
    public ArticleSimpleTypeRecord[] getSizes() {
        return (ArticleSimpleTypeRecord[]) get(29);
    }

    /**
     * Setter for <code>shop.article_view.av_all_model_colors</code>.
     */
    public ArticleViewRecord setAllModelColors(SameModelArticleTypeRecord[] value) {
        set(30, value);
        return this;
    }

    /**
     * Getter for <code>shop.article_view.av_all_model_colors</code>.
     */
    @Column(name = "av_all_model_colors")
    public SameModelArticleTypeRecord[] getAllModelColors() {
        return (SameModelArticleTypeRecord[]) get(30);
    }

    // -------------------------------------------------------------------------
    // Constructors
    // -------------------------------------------------------------------------

    /**
     * Create a detached ArticleViewRecord
     */
    public ArticleViewRecord() {
        super(ArticleView.ACTIVE_ARTICLE_VIEW);
    }

    /**
     * Create a detached, initialised ArticleViewRecord
     */
    public ArticleViewRecord(Long article_id, Long article_model_id, String article_name, String article_name_for_url, Season article_season, Short article_year, Boolean article_standard_size_designation, String article_ean13, String article_config_sku, JsonElement article_features, Color article_color, Color article_color2, Color article_color3, JsonElement article_color_detail, LocalizedMoneyRecord[] article_paid_price, LocalizedMoneyRecord[] article_price, String[] article_image_filenames, Timestamp article_active_from, Discount article_discount, Short brand_id, String brand_name, String brand_name_for_url, BrandCountry brand_country, String brand_logo_url, JsonElement brand_facts, Long commodity_group_id, String commodity_group_name, String commodity_group_name_for_url, CategoryTypeRecord[] categories, ArticleSimpleTypeRecord[] sizes, SameModelArticleTypeRecord[] all_model_colors) {
        super(ArticleView.ACTIVE_ARTICLE_VIEW);

        set(0, article_id);
        set(1, article_model_id);
        set(2, article_name);
        set(3, article_name_for_url);
        set(4, article_season);
        set(5, article_year);
        set(6, article_standard_size_designation);
        set(7, article_ean13);
        set(8, article_config_sku);
        set(9, article_features);
        set(10, article_color);
        set(11, article_color2);
        set(12, article_color3);
        set(13, article_color_detail);
        set(14, article_paid_price);
        set(15, article_price);
        set(16, article_image_filenames);
        set(17, article_active_from);
        set(18, article_discount);
        set(19, brand_id);
        set(20, brand_name);
        set(21, brand_name_for_url);
        set(22, brand_country);
        set(23, brand_logo_url);
        set(24, brand_facts);
        set(25, commodity_group_id);
        set(26, commodity_group_name);
        set(27, commodity_group_name_for_url);
        set(28, categories);
        set(29, sizes);
        set(30, all_model_colors);
    }
}

问题的可能来源

我按照Andrew Rueckert的链接进行了调试,但似乎问题出在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;
    }
    

    它将使用方法pgSetValue对象中的值将值设置到记录中。

    在设置jsonvalue的值时,jOOQ调用方法pgSetValue(记录,字段

    pgFromString中,行

    else {
        Converter<Object, T> c = (Converter<Object, T>) converter;
        return c.from(pgFromString(c.fromType(), string));
    }
    

    问题来了,因为json转换器应该将值转换为json,从pgFromString(c.fromType(),string)返回的对象开始,但是由于c.fromType()返回Object并且jOOQ中没有对象的默认绑定,因此它一次又一次地转到默认情况,我们得到了StackOverflowException

    我看了一下那门课的变化,现在的老师似乎已经解决了这个问题。现在有:

        else if (type == Object.class) {
            return (T) string;
        }
    

    然后,我必须等待下一个jOOQ小版本。我希望它很快就来。


  • 共有1个答案

    欧阳成弘
    2023-03-14

    您是否为JsonElement注册了自定义绑定?我们也使用Gson类型,并且必须执行以下操作:

    波姆。xml(缩写)

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

    GsonJsonBinding.java

    public class GsonJsonBinding extends GenericStringlikeBinding<JsonElement> {
       public GsonJsonBinding() {
           super("json", new 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;
        }
    }
    
     类似资料:
    • 在hbase中,我有很多列:name,city,... 不是所有列都有值(例如,有些行只能有'name') 我想提取一行中的所有列+列的时间戳(按特定顺序),如果值为null,我想返回空字符串。 我面临的问题是,我必须通过'family'和'qualifier'访问中的列(我不能通过的索引访问,因为空值被跳过)

    • 我在这里浏览了关于在Jooq中将记录提取到可变pojo中的文档。 它说列被映射到最佳匹配的构造函数、属性或setter。 谁能分享更多的信息最佳匹配属性或setter意味着什么?

    • 问题内容: 我的程序中随机生成了一些UUID,但是我希望能够提取生成的UUID的时间戳以进行测试。我注意到使用访问器可以获取时间戳的各个部分,但是我不知道如何组合它们。 问题答案: 在/usr/lib/python2.6/uuid.py内部,您会看到 解决time.time()的方程,您将获得 因此使用: 这给出了与生成的UUID关联的日期时间。

    • 我在1998-01-01到1998-12-31期间使用TRMM_3B42_Daily产品创建了这个文件。这是我在R中使用的脚本: 通过这个链接,我试图提取值来绘制时间序列,但似乎我正在平均两个单元格的值,而不仅仅是提取单个单元格的值。我该如何解决这个问题?有没有办法创建一个循环,以便它提取不同单元格的值?(在这种情况下,它将是13 x 21=273) 我还发现了另外两个问题,即 excel 文件中

    • 当我运行第一段时,它非常好并生成输出。但是在第二种情况下,当我运行这个段2时,它生成 第1部分: 第2部分: