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

Spring JDBC保存实体报错:PSQLException: relation 'complex'不存在

解决Spring Data JPA将JSONB列识别为关联表的问题

问题根源

Spring Data JPA默认会把Complex、Developer这类嵌套实体解析为数据库关联表,因此生成了插入complex表的错误SQL,而实际需求是将这些嵌套对象序列化为JSON格式,存入development表的JSONB列。

解决方案

方案一:自定义Jackson属性转换器

通过自定义转换器,实现嵌套对象与JSON字符串的双向转换,明确告诉框架如何处理JSONB列的映射。

  1. 创建通用JSON转换器
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;
import java.io.IOException;

@Converter(autoApply = true)
public class JacksonJsonConverter<T> implements AttributeConverter<T, String> {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public String convertToDatabaseColumn(T attribute) {
        if (attribute == null) {
            return null;
        }
        try {
            return objectMapper.writeValueAsString(attribute);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException("无法序列化对象为JSON", e);
        }
    }

    @Override
    public T convertToEntityAttribute(String dbData) {
        if (dbData == null) {
            return null;
        }
        try {
            return (T) objectMapper.readValue(dbData, Object.class);
        } catch (IOException e) {
            throw new IllegalArgumentException("无法反序列化JSON为对象", e);
        }
    }
}
  1. 修改Development实体类字段注解
@Table(name = "development")
public class Development {

    @Id
    private String id;

    @Column(columnDefinition = "jsonb")
    @Convert(converter = JacksonJsonConverter.class)
    private Complex complex;

    @Column(columnDefinition = "jsonb")
    @Convert(converter = JacksonJsonConverter.class)
    private Developer developer;

    private String comment;

    @CreatedDate
    @Column(name = "created_at")
    private Instant createdAt;
}

方案二:使用Hibernate Types库(JPA+Hibernate场景)

借助第三方库简化JSONB类型的映射配置。

  1. 添加Maven依赖
<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-55</artifactId>
    <version>2.20.0</version>
</dependency>
  1. 修改实体类字段注解
@Table(name = "development")
public class Development {

    @Id
    private String id;

    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private Complex complex;

    @Type(type = "jsonb")
    @Column(columnDefinition = "jsonb")
    private Developer developer;

    private String comment;

    @CreatedDate
    @Column(name = "created_at")
    private Instant createdAt;
}

方案三:Spring Data JDBC专属配置

如果实际使用的是Spring Data JDBC而非JPA,直接使用@JdbcTypeCode注解指定JSON类型:

@Table(name = "development")
public class Development {

    @Id
    private String id;

    @JdbcTypeCode(SqlTypes.JSON)
    private Complex complex;

    @JdbcTypeCode(SqlTypes.JSON)
    private Developer developer;

    private String comment;

    @CreatedDate
    @Column(name = "created_at")
    private Instant createdAt;
}

额外注意事项

  • 确保Complex实体类已正确定义(你提供的代码中仅包含Apartment和Developer,需补充对应类)
  • 实体类字段名与数据库列名需匹配,比如createdAt需通过@Column(name = "created_at")映射到数据库的created_at列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 13:20:22