Spring Data JPA查询Postgres JSONB数据返回无引号问题求助
解决Spring Data JPA查询PostgreSQL JSONB返回结果缺失双引号的问题
我来帮你搞定这个头疼的问题!先从几个核心方向排查和解决:
一、先检查实体类字段类型是否正确
很多时候出现这种问题,是因为实体类里对应JSONB的字段误用了String类型——Spring Data JPA默认会把数据库里的JSONB值直接转成不带JSON结构的字符串,自然就丢了双引号。
推荐的字段类型映射
改用Jackson的JsonNode或者自定义DTO类来映射JSONB字段,这样Spring Data JPA会自动保留完整的JSON结构:
import com.fasterxml.jackson.databind.JsonNode; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import org.hibernate.annotations.JdbcTypeCode; import org.hibernate.type.SqlTypes; @Entity public class YourEntity { @Id private Long id; // 用JsonNode映射JSONB字段,自动保留JSON结构 @Column(columnDefinition = "jsonb") @JdbcTypeCode(SqlTypes.JSON) private JsonNode data; // getter和setter方法 }
查询后直接调用data.toString(),就能得到带双引号的标准JSON字符串了。
二、如果必须用String类型,自定义转换规则
要是你因为业务原因必须用String存储JSONB字段,可以通过自定义AttributeConverter来强制保留JSON格式:
import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; @Converter(autoApply = true) public class JsonbToStringConverter implements AttributeConverter<String, String> { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public String convertToDatabaseColumn(String attribute) { // 存储前验证JSON格式,避免存入不规范内容 try { objectMapper.readTree(attribute); return attribute; } catch (JsonProcessingException e) { throw new IllegalArgumentException("传入的不是标准JSON字符串", e); } } @Override public String convertToEntityAttribute(String dbData) { // 查询返回时直接返回数据库里的原始JSON字符串 return dbData; } }
然后在实体类字段上标注这个转换器:
@Entity public class YourEntity { @Id private Long id; @Column(columnDefinition = "jsonb") @Convert(converter = JsonbToStringConverter.class) private String data; // getter和setter方法 }
三、排查数据库中存储的JSON是否规范
你提到数据库里存的是"{ "name":"abc", "place"="xyz" }"——这里place后面是等号,不是JSON标准的冒号!这本身就是不规范的JSON,也是你用Gson/ObjectMapper转换失败的核心原因。
先修复数据库里的不规范数据:
UPDATE your_table SET data = REPLACE(data::text, 'place=', 'place:')::jsonb;
修复后再用上面的方法处理,转换就能正常工作了。
四、原生查询的正确姿势
如果用原生SQL查询,要确保直接返回JSONB类型,别转成text后再处理:
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import com.fasterxml.jackson.databind.JsonNode; public interface YourRepository extends CrudRepository<YourEntity, Long> { @Query(value = "SELECT data FROM your_table WHERE id = ?1", nativeQuery = true) JsonNode findDataById(Long id); }
返回的JsonNode自带完整JSON结构,转成字符串后双引号自然就回来了。
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

