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

GORM Gen数据库转结构体时JSON字段空值写入报错解决方案求助

解决方案:GORM Gen插入JSON字段空值报错问题

针对你遇到的插入记录时未传递JSON字段(other/card)触发Error 3140 (22032): Invalid JSON text错误的问题,以下是几个可行的解决办法:

方案1:修改数据库表,为JSON字段设置默认空JSON对象

直接从数据库层面解决,给JSON字段添加DEFAULT '{}'(或DEFAULT '[]',根据业务需求选择),这样插入时未传值会自动使用默认的合法JSON值,避免报错。

执行SQL修改表:

ALTER TABLE `user_profile` 
MODIFY COLUMN `other` json NOT NULL DEFAULT '{}' COMMENT 'other personal information',
MODIFY COLUMN `card` json NOT NULL DEFAULT '{}' COMMENT 'introduction card';

注:如果业务允许JSON字段为NULL,也可以保留原字段的可空属性,此时插入未传值时数据库会自动填充NULL,不会触发JSON格式错误。

方案2:修改GORM Gen生成的结构体,使用指针类型或设置零值

如果不想修改数据库,可以调整生成的结构体字段:

  • 将JSON字段改为指针类型:当未传递值时,字段为nil,GORM会将其映射为数据库的NULL,而MySQL允许JSON字段为NULL,不会报错。
    示例结构体:
    type UserProfile struct {
        UUID        string         `gorm:"column:uuid;type:varchar(50);not null;unique;comment:uuid"`
        UserID      int            `gorm:"column:user_id;type:int;not null;primaryKey;comment:user id"`
        Nickname    string         `gorm:"column:nickname;type:varchar(20);not null;default:'';comment:nickname"`
        Age         int8           `gorm:"column:age;type:tinyint;not null;default:0;comment:age"`
        Active      bool           `gorm:"column:active;type:bool;not null;default:true;comment:whether the user is active"`
        Rank        float32        `gorm:"column:rank;type:float;not null;default:0;comment:user rank"`
        Other       *json.RawMessage `gorm:"column:other;type:json;comment:other personal information"`
        Card        *json.RawMessage `gorm:"column:card;type:json;comment:introduction card"`
        State       string         `gorm:"column:state;type:enum('on','off');not null;default:'on';comment:blacklist: off - on"`
        IsDel       int8           `gorm:"column:is_del;type:tinyint;not null;default:0;comment:whether the record is deleted"`
        CreateTime  time.Time      `gorm:"column:create_time;type:datetime;not null;default:CURRENT_TIMESTAMP;comment:the time when the record is created"`
        UpdateTime  time.Time      `gorm:"column:update_time;type:datetime;not null;default:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;comment:the time when the record is updated"`
    }
    
  • 或者在创建结构体实例时,主动给JSON字段设置默认的空JSON对象:
    profile := &UserProfile{
        // 其他必填字段赋值
        Other: json.RawMessage("{}"),
        Card: json.RawMessage("{}"),
    }
    db.Create(profile)
    

方案3:自定义JSON字段类型,处理空值映射

定义一个自定义类型,实现GORM所需的Scanner和Valuer接口,自动将空值转换为合法的JSON值:

type JSONRaw json.RawMessage

// Value 将类型转换为数据库可接受的格式
func (j JSONRaw) Value() (driver.Value, error) {
    if len(j) == 0 {
        return []byte("{}"), nil
    }
    return json.RawMessage(j).Value()
}

// Scanner 从数据库读取值并转换为自定义类型
func (j *JSONRaw) Scan(value interface{}) error {
    return (*json.RawMessage)(j).Scan(value)
}

然后在结构体中使用这个自定义类型:

type UserProfile struct {
    // ... 其他字段
    Other JSONRaw `gorm:"column:other;type:json;comment:other personal information"`
    Card  JSONRaw `gorm:"column:card;type:json;comment:introduction card"`
    // ... 其他字段
}

这样当字段为空时,会自动插入{}作为JSON值,避免格式错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 20:55:34