在Spring Data JPA中能否将NaN作为NULL处理?
问题答复
Hibernate/JPA 没有内置的全局配置项可以直接实现将Postgres返回的NaN值自动转为NULL处理,但可以通过以下标准方案实现需求,无需修改业务逻辑:
方案1:全局统一处理(推荐)
通过JPA标准的AttributeConverter实现全局转换,所有实体类的BigDecimal字段会自动适配:
- 编写转换器类
import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; import java.math.BigDecimal; // autoApply = true 表示对所有BigDecimal字段自动生效 @Converter(autoApply = true) public class BigDecimalNaNToNullConverter implements AttributeConverter<BigDecimal, Object> { @Override public Object convertToDatabaseColumn(BigDecimal attribute) { // 写入数据库逻辑:业务用NULL就直接返回,需要存NaN可改为返回 attribute == null ? Double.NaN : attribute return attribute; } @Override public BigDecimal convertToEntityAttribute(Object dbData) { if (dbData == null) { return null; } // 识别NaN值转为NULL if (dbData instanceof Number) { double doubleVal = ((Number) dbData).doubleValue(); if (Double.isNaN(doubleVal)) { return null; } return BigDecimal.valueOf(doubleVal); } return new BigDecimal(dbData.toString()); } }
将该类放入你的项目实体/DAO层的扫描路径即可自动生效。
方案2:指定字段单独处理
如果不需要全局生效,仅部分金额字段需要适配NaN:
- 将上述转换器的
autoApply属性改为false - 在需要适配的实体类字段上添加转换注解即可:
@Column(name = "transaction_amount") @Convert(converter = BigDecimalNaNToNullConverter.class) private BigDecimal transactionAmount;
补充说明:Postgres的numeric类型NaN值在JDBC驱动中默认会以Double类型的NaN返回,上述转换器已经覆盖了该场景,你也可以根据自身业务需要调整写入逻辑,比如将实体类的NULL值转为NaN存入数据库。
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

