如何将带有hypen的mysql枚举类型映射到JPA实体?

时间:2019-09-25 14:35:11

标签: java mysql hibernate jpa

mysql vim81diff中有一个表,其中的字段sakila.film类型为rating

我正在尝试使用类型enum('G','PG','PG-13','R','NC-17')enum在JPA实体中进行映射,但是无法映射,因为Java枚举不允许连字符。 也无法更改或更新表,因为它具有大量数据并给出错误-“数据被截断以用于列'rating'”

如何进行?

1 个答案:

答案 0 :(得分:1)

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属性。

我个人通常将转换器作为静态类嵌套在它们转换的类中,但是如果您希望将它们分开,则不必这样做。