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

hpxqektj  于 2023-10-23  发布在  其他
关注(0)|答案(2)|浏览(147)

在Sping Boot 3.1.4中使用最新的Hibernate 6.3.1.Final的遗留数据库模式需要进行JPA模型所需的大量代码迁移工作。我目前的大部分问题都与枚举类型有关。我在mysql数据库中遇到过Enums存储为int(11)产生“expecting #TINYINT”错误的问题,我只能通过改变db中的列类型来解决(这会破坏遗留代码)。我尝试了这些对注解的更改,但没有效果,而且我在博客中找不到任何其他解决方案。注意:我在Hibernate 6.0.1.Final中没有这些验证问题:
@Column(name=“status”,columnDefinition =“INTEGER”)或@Column(name=“status”,columnDefinition =“int2”)
另一个问题是“@Enumerated(EnumType.STRING)",它似乎根本不起作用。来自www.example.com的文档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','inactive')(Types#ENUM)]
同样,我在Hibernate 6.0.1.Final中没有遇到这个问题。
我应该对Mysql db中存储为int(11)或varchar(255)的Enums的注解做什么更改?

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;
    }
    

}
sqougxex

sqougxex1#

根据https://docs.jboss.org/hibernate/orm/6.3/introduction/html_single/Hibernate_Introduction.html@Enumerated(EnumType.STRING)Map到varchar,除了Mysql(可能还有MariaDB),它Map到ENUM列类型。
如果您更改:@Column(name = "status", nullable = false)到:
@Column(name = "status", nullable = false, columnDefinition = "varchar")
你可以让Hibernate明白这是一个varchar列。

jm81lzqq

jm81lzqq2#

我认为你应该使用自定义转换器。我给出了一个datatypevarchar在你的数据库中的例子,即@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

相关问题