Spring JDBC保存实体报错:PSQLException: relation 'complex'不存在
解决Spring Data JPA将JSONB列识别为关联表的问题
问题根源
Spring Data JPA默认会把Complex、Developer这类嵌套实体解析为数据库关联表,因此生成了插入complex表的错误SQL,而实际需求是将这些嵌套对象序列化为JSON格式,存入development表的JSONB列。
解决方案
方案一:自定义Jackson属性转换器
通过自定义转换器,实现嵌套对象与JSON字符串的双向转换,明确告诉框架如何处理JSONB列的映射。
- 创建通用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); } } }
- 修改
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类型的映射配置。
- 添加Maven依赖
<dependency> <groupId>com.vladmihalcea</groupId> <artifactId>hibernate-types-55</artifactId> <version>2.20.0</version> </dependency>
- 修改实体类字段注解
@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
相关产品推荐
相关产品推荐

