AttributeConverter与PostgreSQL jsonb兼容报错求助:类型不匹配
解决PostgreSQL jsonb字段与AttributeConverter类型不匹配问题
问题原因
你的AttributeConverter将ReminderParameters转换为String类型,但PostgreSQL的jsonb字段需要接收JSON类型数据,JDBC驱动会把String识别为character varying,导致类型不匹配报错。
解决方案:修改Converter适配PGobject
PostgreSQL JDBC驱动提供了PGobject类来处理特殊数据库类型,我们可以修改Converter,将对象转换为PGobject而非String,明确指定类型为jsonb。
修改后的代码
@Entity @Table(name = "scan_reminder_config") public class ScanReminderConfig { @Convert(converter = ReminderParameters.ReminderParametersConverter.class) @Column(name = "cloud_reminder_parameters", columnDefinition = "jsonb") private ReminderParameters cloudReminderParameters; public static class ReminderParameters { private String timezone; // 请补充getter/setter方法 @Converter(autoApply = true) public static class ReminderParametersConverter implements AttributeConverter<ReminderParameters, PGobject> { private final ObjectMapper objectMapper = new ObjectMapper(); @Override public PGobject convertToDatabaseColumn(final ReminderParameters reminderParameters) { PGobject pgObject = new PGobject(); pgObject.setType("jsonb"); try { pgObject.setValue(objectMapper.writeValueAsString(reminderParameters)); } catch (JsonProcessingException | SQLException e) { throw new RuntimeException("Failed to convert ReminderParameters to jsonb", e); } return pgObject; } @Override public ReminderParameters convertToEntityAttribute(final PGobject dataValue) { if (dataValue == null || dataValue.getValue() == null) { return null; } try { return objectMapper.readValue(dataValue.getValue(), ReminderParameters.class); } catch (JsonProcessingException e) { throw new RuntimeException("Failed to convert jsonb to ReminderParameters", e); } } } } }
注意事项
- 确保项目引入了PostgreSQL JDBC驱动(建议版本42.2+),Maven依赖示例:
<dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.3</version> </dependency> - 不要吞掉异常,将转换失败的异常包装为运行时异常抛出,方便排查问题。
替代方案:使用Hibernate原生JSON类型支持
如果你的项目使用Hibernate 5.2及以上版本,可直接用@Type注解简化实现,无需自定义Converter:
@Entity @Table(name = "scan_reminder_config") public class ScanReminderConfig { @Type(type = "jsonb") @Column(name = "cloud_reminder_parameters", columnDefinition = "jsonb") private ReminderParameters cloudReminderParameters; // 其他代码... }
内容的提问来源于stack exchange,提问作者Alan Sun
相关产品推荐
相关产品推荐

