EntityManager原生查询如何无需name方法保存枚举名称?
解决EntityManager原生查询中直接传入枚举保存名称的问题
直接传入枚举对象出现\xaced00057e72002c636f6dffddffd...这类序列化乱码,是因为JPA默认会把枚举对象序列化为字节码存储,而非自动取枚举的name()值。以下是几种不用手动调用name()也能保存枚举名称,同时避免空指针的方法:
方法1:自定义枚举参数转换器(推荐全局处理)
实现JPA的AttributeConverter接口,定义枚举与数据库字符串的转换规则,空值也能自动处理:
import javax.persistence.AttributeConverter; import javax.persistence.Converter; // autoApply=true 表示全局所有该类型枚举都会自动应用这个转换器 @Converter(autoApply = true) public class YourEnumConverter implements AttributeConverter<YourEnumType, String> { @Override public String convertToDatabaseColumn(YourEnumType enumVal) { // 空枚举返回null,非空返回枚举名称 return enumVal != null ? enumVal.name() : null; } @Override public YourEnumType convertToEntityAttribute(String dbValue) { // 数据库值为null返回null,否则转换为对应枚举 return dbValue != null ? YourEnumType.valueOf(dbValue) : null; } }
写完转换器后,直接传入枚举对象即可,JPA会自动帮你转成name()值,空值也不会触发空指针:
entityManager.createNativeQuery( "INSERT INTO car(enum_column) VALUES(:enumColumn)") .unwrap(NativeQuery.class) .setParameter("enumColumn", entity.getEnumColumn) .executeUpdate();
方法2:用JPQL替代原生查询(如果场景允许)
如果不需要写原生SQL,用JPQL的话,JPA会自动处理枚举到name()的转换,空值也能正常处理:
entityManager.createQuery( "INSERT INTO Car(enumColumn) VALUES (:enumColumn)", Car.class) .setParameter("enumColumn", entity.getEnumColumn()) .executeUpdate();
方法3:封装工具方法简化空判断
如果一定要用原生查询,又不想每次写空判断,可以封装一个工具方法:
public static String getEnumSafeName(Enum<?> enumVal) { return enumVal != null ? enumVal.name() : null; }
调用时直接传枚举对象即可:
entityManager.createNativeQuery( "INSERT INTO car(enum_column) VALUES(:enumColumn)") .unwrap(NativeQuery.class) .setParameter("enumColumn", getEnumSafeName(entity.getEnumColumn)) .executeUpdate();
内容的提问来源于stack exchange,提问作者pawello12
相关产品推荐
相关产品推荐

