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

Spring Boot 3下JPA无法识别自定义Item类的JdbcType问题求助

解决Spring Boot 3 + Hibernate中自定义类List以JSON存储到MySQL的问题

Hibernate抛出JdbcTypeRecommendationException的核心原因是:它无法自动推断自定义Item类对应的JDBC类型,仅靠@Column(columnDefinition="JSON")只能指定数据库字段类型,无法告诉Hibernate如何序列化/反序列化Java对象与JSON数据。

以下是两种可行的解决方案:

方法一:使用Hibernate 6+的@JdbcTypeCode注解(推荐)

Spring Boot 3默认搭配Hibernate 6,该版本引入了@JdbcTypeCode注解,可以直接指定JSON类型的映射:

  1. 在Quote类的items字段上同时添加@Column(columnDefinition = "JSON")和@JdbcTypeCode(SqlTypes.JSON):
import jakarta.persistence.*;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.type.SqlTypes;
import java.util.List;

@Entity
@Table(name = "quotes")
public class Quote {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // 其他业务字段示例
    private String quoteNumber;
    private Long customerId;

    @Column(columnDefinition = "JSON")
    @JdbcTypeCode(SqlTypes.JSON)
    private List<Item> items;

    // 无参构造器(JPA要求)
    public Quote() {}

    // 带参构造器、Getter、Setter省略
}
  1. 确保Item类支持Jackson序列化:
    • 提供无参构造器(Jackson默认依赖)
    • 为字段提供Getter方法(或用Lombok简化)
import java.math.BigDecimal;

public class Item {
    private String productName;
    private BigDecimal unitPrice;
    private int quantity;

    public Item() {}

    public Item(String productName, BigDecimal unitPrice, int quantity) {
        this.productName = productName;
        this.unitPrice = unitPrice;
        this.quantity = quantity;
    }

    // Getter、Setter省略
}

方法二:自定义AttributeConverter实现序列化逻辑

如果需要更灵活的序列化控制(比如自定义字段过滤、日期格式),可以实现Hibernate的AttributeConverter:

  1. 编写转换器类:
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;

@Converter(autoApply = false)
public class ItemListJsonConverter implements AttributeConverter<List<Item>, String> {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public String convertToDatabaseColumn(List<Item> items) {
        try {
            return objectMapper.writeValueAsString(items);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("序列化Item列表失败", e);
        }
    }

    @Override
    public List<Item> convertToEntityAttribute(String jsonString) {
        try {
            return objectMapper.readValue(jsonString, new TypeReference<List<Item>>() {});
        } catch (JsonProcessingException e) {
            throw new RuntimeException("反序列化JSON到Item列表失败", e);
        }
    }
}
  1. 在Quote类的items字段上关联转换器:
@Column(columnDefinition = "JSON")
@Convert(converter = ItemListJsonConverter.class)
private List<Item> items;

注意事项

  • MySQL版本需支持JSON类型(5.7及以上)
  • 若使用Lombok,可给Item类添加@Data+@NoArgsConstructor注解简化代码
  • Spring Boot Web Starter默认包含Jackson依赖,无需额外引入

内容的提问来源于stack exchange,提问作者Niccolò Cavallini

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 04:15:21