Spring Boot3+Hibernate6迁移:Cloud Spanner JSON字段插入失败求助
解决方案
1. 用@ColumnTransformer强制适配Spanner JSON格式要求
Spanner的JSON列要求插入值必须通过JSON()函数包裹,直接传入字符串会触发类型不匹配错误。可以通过@ColumnTransformer显式指定写入逻辑:
import org.hibernate.annotations.ColumnTransformer; import jakarta.persistence.Column; import org.hibernate.type.SqlTypes; import org.hibernate.annotations.JdbcTypeCode; @Column(name = "Filter", columnDefinition = "JSON") @ColumnTransformer( write = "JSON(?)", // 写入时自动用Spanner的JSON函数包裹序列化后的字符串 read = "Filter" // 读取时直接返回列值 ) @JdbcTypeCode(SqlTypes.STRING) // 将Java对象序列化为字符串后传入 private Filter filter;
2. 确保Java对象可正常序列化为JSON字符串
- 给
Filter类添加@Getter/@Setter(或手动实现访问器) - 若包含复杂字段,添加Jackson注解(如
@JsonProperty、@JsonIgnore)确保序列化逻辑正确
3. 替换为Hibernate 6兼容的Spanner方言
将原配置的org.hibernate.dialect.SpannerDialect替换为适配Hibernate 6的版本:
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.CloudSpannerDialect
4. 启用Hibernate的Jackson JSON支持
在配置文件中添加属性,让Hibernate优先使用Jackson处理JSON序列化:
spring.jpa.properties.hibernate.type.preferred_json_jackson=true
5. 自定义Hibernate JSON类型(进阶方案)
若上述方法仍无效,可自定义适配Spanner的JSON类型:
import com.fasterxml.jackson.databind.ObjectMapper; import org.hibernate.type.AbstractSingleColumnStandardBasicType; import org.hibernate.type.descriptor.java.JsonJavaTypeDescriptor; import org.hibernate.type.descriptor.jdbc.VarcharJdbcType; public class SpannerJsonType<T> extends AbstractSingleColumnStandardBasicType<T> { public SpannerJsonType(ObjectMapper objectMapper) { super( VarcharJdbcType.INSTANCE, (JsonJavaTypeDescriptor<T>) JsonJavaTypeDescriptor.from(objectMapper) ); } @Override public String getName() { return "spanner-json"; } }
然后在实体类中引用:
@Type(type = "com.yourpackage.SpannerJsonType") @Column(name = "Filter", columnDefinition = "JSON") private Filter filter;
内容的提问来源于stack exchange,提问作者anton.rynkovoy
相关产品推荐
相关产品推荐

