内部属性不会在 JOOQ 中自动转换

Posted

技术标签:

【中文标题】内部属性不会在 JOOQ 中自动转换【英文标题】:Inner property is not automatically cast in JOOQ 【发布时间】:2020-02-12 10:51:44 【问题描述】:

我有如下表格:

    CREATE TABLE recipes
(
  id INT AUTO_INCREMENT,
  name VARCHAR(100) NOT NULL,
  components JSON,
  active BOOLEAN NULL DEFAULT TRUE,

  PRIMARY KEY (id),
  UNIQUE KEY (name)
)
  CHARACTER SET "UTF8"
  ENGINE = InnoDb;

我创建了如下的 pojo 类:

@JsonIgnoreProperties(ignoreUnknown = true)
public class CValueRecipeV2

    @JsonProperty("components")
    @JsonAlias("matcher.components")
    @Column(name = "components")
    @Valid
    private List<CComponentV2> mComponents;

    @JsonProperty("name")
    @Column(name = "name")
    private String name;

    public List<CComponentV2> getComponents()
    
        return mComponents;
    

    public void setComponents(List<CComponentV2> mComponents)
    
        this.mComponents = mComponents;
    
    public String getName()
    
        return mName;
    

    public void setName(String mName)
    
        this.mName = mName;
    


另一个类

@JsonIgnoreProperties(ignoreUnknown = true)
public class CComponentV2

    @JsonProperty("shingle_size")
    @JsonAlias("shingleSize")
    @CShingleField
    private Integer mShingleSize;

    public Integer getmShingleSize()
    
        return mShingleSize;
    

    public void setmShingleSize(Integer mShingleSize)
    
        this.mShingleSize = mShingleSize;
    

现在我正在尝试使用 JOOQ 从数据库中获取记录。 但是我无法将 json 组件字符串转换为组件类。

我正在读取下表中的数据:

context.dsl().select(RECIPES.asterisk())
                        .from(RECIPES)
                        .where(RECIPES.NAME.eq(name))
                        .fetchInto(CValueRecipeV2.class);

在数据库中,我有以下记录。

ID name components           active
1  a    ["shingle_size=2"] true

在获取数据时,我收到以下错误

Caused by: org.jooq.exception.DataTypeException: Cannot convert from shingle_size=2 (class java.util.HashMap) to class com.ac.config_objects.CComponentV2

我是 JOOQ 的新手。如果我遗漏了什么,请告诉我。 提前致谢。

【问题讨论】:

【参考方案1】:

我已经使用 jooq 转换器解决了我的问题。

var record = context.dsl().select(RECIPES.asterisk())
                        .from(RECIPES)
                        .where(RECIPES.NAME.eq(name))
                        .fetchOne();

                record.setValue(RECIPES.COMPONENTS, record.get(RECIPES.COMPONENTS, new CComponentV2Converter()));
                var recipe = record.into(CValueRecipeV2.class);

我的转换器如下所示:

public class CComponentV2Converter implements Converter<Object, List<CComponentV2>>

    static final long serialVersionUID = 0;

    @Override
    public List<CComponentV2> from(Object databaseObject)
    
        var componentList = CObjectCaster.toMapList(databaseObject);
        List<CComponentV2> cComponentV2s = new ArrayList<>();
        componentList.forEach(e -> 
            CComponentV2 cComponentV2 = new CComponentV2();
            cComponentV2.setmShingleSize(CObjectCaster.toInteger(e.get("shingle_size")));
            cComponentV2s.add(cComponentV2);
        );
        return cComponentV2s;
    

【讨论】:

【参考方案2】:

jOOQ 不理解您的 @JsonProperty 和其他开箱即用的注释。您必须实现自己的记录映射器来支持它们: https://www.jooq.org/doc/latest/manual/sql-execution/fetching/pojos-with-recordmapper-provider/

【讨论】:

以上是关于内部属性不会在 JOOQ 中自动转换的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL 函数 + 在 jOOQ 中强制转换

JOOQ 使用转换器将字符串转换为枚举

如何在 jOOQ 中转换“to_json()”PostgreSQL 函数?

Jooq 与 POJO 转换器

使用 jOOQ 使用正确的类型转换从 values() 中选择插入

使用 Spring Boot 进行 JOOQ SQL 语法转换