代码之家  ›  专栏  ›  技术社区  ›  user2989397

Hibernate 6.3.1.最终Mariadb@Enumerated(EnumType.STRING)不工作

  •  0
  • user2989397  · 技术社区  · 1 年前

    使用最新的Hibernate 6.3.1.Final和Spring Boot 3.1.4的遗留数据库模式已经完成了JPA模型所需的大量代码迁移工作。我目前的大多数问题都与枚举类型有关。我遇到过mysql数据库中存储为int(11)的Enum的问题,这些Enum会产生“预期#TINYINT”错误,我只能通过更改数据库中的列类型来解决这个问题(这会破坏遗留代码)。我尝试过对注释进行这些更改,但没有成功,在博客中找不到任何其他解决方案。注意:我在Hibernate 6.0.1.Final中没有这些验证问题:

    @列(name=“status”,columnDefinition=“INTEGER”) 或 @列(name=“status”,columnDefinition=“int2”)

    另一个问题是“@Enumerated(EnumType.STRING)”,它似乎根本不起作用。文档来自 https://docs.jboss.org/hibernate/orm/6.3/introduction/html_single/Hibernate_Introduction.html#enums 不完整或不再准确。我在遗留数据库中有一个枚举存储为“varchar(255)”,具有以下JPA定义:

    @Column(name = "status", nullable = false)
    @Enumerated(EnumType.STRING)
    @Basic(optional=false)
    private ActiveOrInactive status;
    

    我在验证时得到以下错误:

    找到[varchar(Types#varchar)],但应为[enum('active','active')(Types#enum)]

    同样,我在Hibernate 6.0.1.Final中没有遇到这个问题。

    我应该对Mysql-db中存储为int(11)或varchar(255)的枚举的注释进行哪些更改?

    import java.util.HashMap;
    import java.util.Map;
    
    public enum ActiveOrInactive {
        
        Active, Inactive;
        
        static final Map<String, ActiveOrInactive> _activeOrInactive = new HashMap<String, ActiveOrInactive>();
        static {
            for (ActiveOrInactive activeOrInactive : ActiveOrInactive.values()) {
                _activeOrInactive.put(activeOrInactive.toString(), activeOrInactive);
            }
        }
        
        public static Map<String, ActiveOrInactive> getPublishedStateTypes() {
            return _activeOrInactive;
        }
        
    
    }
    
    0 回复  |  直到 1 年前
        1
  •  1
  •   korsgaard    1 年前

    根据 https://docs.jboss.org/hibernate/orm/6.3/introduction/html_single/Hibernate_Introduction.html @Enumerated(EnumType.STRING) 被映射到varchar,除了Mysql(可能还有MariaDB)被映射到ENUM列类型。

    如果您更改: @Column(name = "status", nullable = false) 至:

    @Column(name = "status", nullable = false, columnDefinition = "varchar")

    您可以让hibernate理解它是一个varchar列。

        2
  •  0
  •   Asgar    1 年前

    我认为您应该为此使用自定义转换器。 我举了一个例子 datatype varchar 在您的数据库中,即。, @Enumerated(EnumType.STRING) ,如果是为了 int ,可以相应地对自定义转换器类进行更改。

    @Converter
    public class ActiveOrInactiveConverter implements Serializable,  AttributeConverter<ActiveOrInactive, String> {
    
        @Override
        public String convertToDatabaseColumn(ActiveOrInactive attribute) {
            if (attribute == null) {
                return null;
            }
            return attribute.name();
        }
    
        @Override
        public ActiveOrInactive convertToEntityAttribute(String dbData) {
            if (dbData == null) {
                return null;
            }
            return ActiveOrInactive.valueOf(dbData);
        }
    }
    

    您应该更换

    @Enumerated(EnumType.STRING)
    

    具有

    @Convert(converter = ActiveOrInactiveConverter.class)
    

    它应该看起来像:

    @Column(name = "status", nullable = false)
    @Convert(converter = ActiveOrInactiveConverter.class)
    @Basic(optional=false)
    private ActiveOrInactive status;
    

    这是一个 reference