我使用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
)!
我激活了DEBUG日志记录模式,我复制了select并在PGAdmin中执行它。有用。 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
。它内部有一个类型。
在课程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;
}
将使用方法pgSetValue
和object
中的值将值设置到记录中。
当设置json
值的值时,jOOQ调用方法pgSetValue(Record record, Field<T> field, String value)
,该方法使用该字段的转换器调用方法pgFromString
(即{{3 }})。问题出在方法pgFromString
中。
在pgFromString
内,第Class<T> type = converter.toType()
行返回com.google.gson.JsonElement
,其未被任何默认值绑定,因此它会转到行:
else {
Converter<Object, T> c = (Converter<Object, T>) converter;
return c.from(pgFromString(c.fromType(), string));
}
问题出现了,因为json转换器应该将值转换为从pgFromString(c.fromType(), string)
返回的对象开始的json,但是因为c.fromType()
返回Object
并且没有默认绑定对于jOOQ中的对象再次出现在默认情况下,并且一次又一次,我们有StackOverflowException
。
我查看了该类中的更改,似乎当前的主人已经解决了这个问题。现在有:
else if (type == Object.class) {
return (T) string;
}
然后,我必须等待下一个jOOQ次要版本。我希望很快就会到来。
答案 0 :(得分:-1)
您是否为JsonElement注册了自定义绑定?我们也使用Gson类型,并且必须执行以下操作:
pom.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;
}
}