You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库多类型转换器实现:处理Odoo JSON RPC返回对象

解决Odoo JSON RPC响应转Room可存储类型的问题

看起来你现在卡在了Object类型无法直接存入Room数据库的问题上,而且当前的类型转换器和实体类设计存在类型不匹配的问题,导致了编译错误。我来一步步帮你解决:

问题根源分析

  1. 实体类中字段声明为Object,但setter方法却接收String等具体类型,getter返回Object,本身就存在类型不一致的矛盾;
  2. 你的类型转换器直接对Object进行强转(比如(String) data),如果Odoo返回的Object实际是Integer/Boolean类型,强转必然报错;
  3. Room无法自动识别Object类型该用哪个转换器,需要明确的类型映射逻辑。

分步解决方案

1. 重构实体类:替换Object为具体类型或JSON字符串

首先,你需要明确Odoo返回的每个字段的实际类型(比如create_date是字符串、ryot_number是数字),把实体类中的Object字段替换成具体的基本类型;对于复杂类型(比如oldEditById这种List),可以转成JSON字符串存储。

修改后的实体类示例:

@Entity(tableName = "ryot")
public class RyotMasterJsonRpcResult {
    @PrimaryKey(autoGenerate = true)
    private Integer ids;

    @SerializedName("create_date")
    @Expose
    private String createDate; // Odoo返回的日期是字符串,直接声明为String

    @SerializedName("ryot_number")
    @Expose
    private Integer ryotNumber; // 假设是数字类型,声明为Integer

    @SerializedName("display_name")
    @Expose
    private String displayName; // 字符串类型

    // 把List<Object>转成JSON字符串存储
    @SerializedName("old_edit_by_id")
    @Expose
    private String oldEditByIdJson;

    // Getter & Setter 严格匹配字段类型
    public Integer getIds() {
        return ids;
    }

    public void setIds(Integer ids) {
        this.ids = ids;
    }

    public String getCreateDate() {
        return createDate;
    }

    public void setCreateDate(String createDate) {
        this.createDate = createDate;
    }

    public Integer getRyotNumber() {
        return ryotNumber;
    }

    public void setRyotNumber(Integer ryotNumber) {
        this.ryotNumber = ryotNumber;
    }

    public String getDisplayName() {
        return displayName;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    // 封装List<Object>的读写逻辑,自动转JSON
    public List<Object> getOldEditById() {
        if (oldEditByIdJson == null || oldEditByIdJson.isEmpty()) {
            return null;
        }
        return new Gson().fromJson(oldEditByIdJson, new TypeToken<List<Object>>() {}.getType());
    }

    public void setOldEditById(List<Object> oldEditById) {
        if (oldEditById == null) {
            this.oldEditByIdJson = null;
            return;
        }
        this.oldEditByIdJson = new Gson().toJson(oldEditById);
    }
}

2. 编写安全的类型转换器

如果还有部分字段需要处理动态类型的Object,要避免直接强转,而是先判断类型再转换;对于复杂类型(比如List),单独写转换器:

public class CommonConverter {
    // 安全处理Object转String,适配不同类型
    @TypeConverter
    public static String objectToString(Object data) {
        if (data == null) {
            return null;
        }
        if (data instanceof String) {
            return (String) data;
        } else if (data instanceof Integer) {
            return data.toString();
        } else if (data instanceof Boolean) {
            return data.toString();
        }
        // 其他复杂类型转JSON字符串
        return new Gson().toJson(data);
    }

    // 安全处理String转Object,自动识别类型
    @TypeConverter
    public static Object stringToObject(String value) {
        if (value == null) {
            return null;
        }
        // 先尝试转Integer
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            // 再尝试转Boolean
            if ("true".equalsIgnoreCase(value) || "false".equalsIgnoreCase(value)) {
                return Boolean.parseBoolean(value);
            }
            // 最后尝试解析为JSON对象,否则返回原字符串
            try {
                return new Gson().fromJson(value, Object.class);
            } catch (JsonSyntaxException ex) {
                return value;
            }
        }
    }

    // List<Object>与JSON字符串的互转
    @TypeConverter
    public static String listObjectToString(List<Object> list) {
        return list == null ? null : new Gson().toJson(list);
    }

    @TypeConverter
    public static List<Object> stringToListObject(String value) {
        return value == null ? null : new Gson().fromJson(value, new TypeToken<List<Object>>() {}.getType());
    }
}

3. 给Room注册转换器

在你的RoomDatabase类上添加@TypeConverters注解,让Room识别这些转换器:

@Database(entities = {RyotMasterJsonRpcResult.class}, version = 1)
@TypeConverters(CommonConverter.class)
public abstract class AppDatabase extends RoomDatabase {
    public abstract RyotDao ryotDao();
}

注意事项

  • 确保你已经在项目中添加了Gson依赖(如果用其他JSON库比如Jackson也可以,逻辑类似);
  • 一定要确认Odoo返回的每个字段的实际类型,比如ryot_number如果是字符串格式的数字,就把实体类字段改成String,避免转换失败;
  • 所有需要存入Room的字段都不能是Object类型,必须转成Room支持的基本类型或JSON字符串。

内容的提问来源于stack exchange,提问作者Rajakrishnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:52:49