Spring Boot应用中Spring Data JPA未使用AttributeConverter问题
解决Spring Boot枚举值大小写转换存储的AttributeConverter实现方案
我来帮你完成这个枚举值转标题大小写存储的实现,结合你给出的实体代码,完整的解决方案如下:
1. 先定义对应的枚举类
假设你的枚举是类似这样的大写下划线格式:
public enum CustomerLeadType { SALES_LEAD, SUPPORT_REQUEST, FEEDBACK_SUBMISSION }
2. 实现AttributeConverter转换器
这个转换器负责在枚举和数据库存储的字符串之间做双向转换:
import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; @Converter(autoApply = true) // 可选:设为true会自动应用到所有该枚举的字段,无需每个字段加@Convert public class CustomerLeadTypeConverter implements AttributeConverter<CustomerLeadType, String> { // 枚举转数据库存储的标题大小写字符串 @Override public String convertToDatabaseColumn(CustomerLeadType attribute) { if (attribute == null) { return null; } // 拆分下划线,转成每个单词首字母大写的格式 String[] wordArray = attribute.name().split("_"); StringBuilder formattedString = new StringBuilder(); for (String word : wordArray) { if (formattedString.length() > 0) { formattedString.append(" "); } formattedString.append(word.substring(0, 1).toUpperCase()) .append(word.substring(1).toLowerCase()); } return formattedString.toString(); } // 数据库字符串转回枚举 @Override public CustomerLeadType convertToEntityAttribute(String dbData) { if (dbData == null || dbData.isBlank()) { return null; } // 拆分空格,转成大写下划线格式匹配枚举name String[] wordArray = dbData.split(" "); StringBuilder enumName = new StringBuilder(); for (String word : wordArray) { if (enumName.length() > 0) { enumName.append("_"); } enumName.append(word.toUpperCase()); } return CustomerLeadType.valueOf(enumName.toString()); } }
3. 修正你的实体类代码
补全你未写完的部分,确保转换器正确关联:
import jakarta.persistence.*; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; import java.io.Serializable; @Entity @Table(name = "customerleads") @Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE) public class CustomerLead implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Enumerated(EnumType.STRING) @Column(name = "type") @Convert(converter = CustomerLeadTypeConverter.class) // 如果转换器没加autoApply=true,必须显式指定 private CustomerLeadType type; // 这里可以添加其他字段、getter/setter、toString等方法 // ... }
关键注意点
- 自动应用开关:如果转换器上的
@Converter(autoApply = true)生效,实体字段上的@Convert注解可以省略,所有使用CustomerLeadType的字段都会自动用这个转换器。 - 空值处理:转换器里一定要处理null/空字符串的情况,避免运行时空指针异常。
- 枚举匹配:转回枚举时,生成的字符串必须和枚举的
name()完全一致(大小写、下划线都要对应),否则会抛出IllegalArgumentException,如果数据库里有脏数据,建议加个try-catch做容错处理。
内容的提问来源于stack exchange,提问作者BHarman
相关产品推荐
相关产品推荐

