在mysql sakila.film中有一个表,其中包含enum('G','PG','PG-13','R','NC-17')类型的字段rating。
我正在尝试使用类型enum和@Enumerated(EnumType.STRING)在JPA实体中映射这一点,但无法实现,因为java枚举不允许连字符。无法更改或更新表,因为它有大量数据,并给出错误-"Data truncated for column 'rating'“
如何继续?
发布于 2019-09-25 22:59:54
这类事情正是JPA Attribute Converters被设计来帮助实现的。
首先,您需要将Java enum元素映射到数据库中的字符串,并提供一个将字符串转换为元素的查找方法:
public enum Rating {
G("G"), // the string arguments should exactly match what's in the database.
PG("PG"),
PG13("PG-13"),
R("R"),
NC17("NC-17");
private static final Map<String, Rating> LOOKUP = Arrays.stream(values())
.collect(Collectors.toMap(Rating::getRating, Function.identity()));
private final String rating;
Rating(final String rating) {
this.rating = rating;
}
public String getRating() {
return rating;
}
public Rating fromString(final String rating) {
// You may want to include handling for the case where the given string
// doesn't map to anything - implementation is up to you.
return LOOKUP.get(rating);
}
}接下来,您将需要一个实现javax.persistence.AttributeConverter的类
public static class RatingConverter implements AttributeConverter<Rating, String> {
@Override
public String convertToDatabaseColumn(final Rating attribute) {
return attribute.getRating();
}
@Override
public Rating convertToEntityAttribute(final String dbData) {
return Rating.fromString(dbData);
}
}在这里,您需要决定是否应该始终应用此转换器(听起来可能应该这样),或者不应该。
如果您希望它始终在您不需要进一步配置的情况下使用,那么可以使用@javax.persistence.Converter(autoApply = true)注释您的转换器类。
如果您希望选择何时使用转换器,那么您将需要将注释@javax.persistence.Convert(converter = RatingConverter.class)添加到每个需要它的JPA实体的Rating属性中。
就我个人而言,我通常将转换器作为静态类嵌套在它们转换的类中,但如果您希望将它们分开,则不必这样做。
https://stackoverflow.com/questions/58100874
复制相似问题