配置休眠(使用 JPA)以存储布尔类型的 Y/N 而不是 0/1

2022-08-31 12:25:12

是否可以将 JPA/休眠设置为将类型持久化为 ?在数据库中(该列定义为 。它当前将它们存储为 .数据库是 Oracle。BooleanY/Nvarchar2(1)0/1


答案 1

Hibernate有一个内置的“yes_no”类型,可以做你想做的事。它映射到数据库中的 CHAR(1) 列。

基本映射:<property name="some_flag" type="yes_no"/>

注释映射(休眠扩展):

@Type(type="yes_no")
public boolean getFlag();

答案 2

这是不使用 getters/setters 的纯 JPA。截至2013/2014年,它是不使用任何Hibernate特定注释的最佳答案,但请注意,此解决方案是JPA 2.1,并且在首次提出问题时不可用:

@Entity
public class Person {    

    @Convert(converter=BooleanToStringConverter.class)
    private Boolean isAlive;    
    ...
}

然后:

@Converter
public class BooleanToStringConverter implements AttributeConverter<Boolean, String> {

    @Override
    public String convertToDatabaseColumn(Boolean value) {        
        return (value != null && value) ? "Y" : "N";            
        }    

    @Override
    public Boolean convertToEntityAttribute(String value) {
        return "Y".equals(value);
        }
    }

编辑:

上面的实现考虑了与字符“Y”不同的任何内容,包括 ,as 。这是对的吗?这里的一些人认为这是不正确的,并认为数据库中应该有Java。nullfalsenullnull

但是,如果您以Java返回,它将为您提供一个如果字段是原始布尔值。换句话说,除非某些字段实际使用类布尔值,否则最好将其视为 ,并使用上述实现。然后,休眠将不会发出任何异常,而不管数据库的内容如何。nullNullPointerExceptionnullfalse

如果您确实想在数据库内容不完全正确的情况下接受并发出异常,那么我想您不应该接受除“Y”,“N”和以外的任何字符。让它保持一致,不要接受任何像“y”,“n”,“0”和“1”这样的变体,这只会让你以后的生活更加艰难。这是一个更严格的实现:nullnull

@Override
public String convertToDatabaseColumn(Boolean value) {
    if (value == null) return null;
    else return value ? "Y" : "N";
    }

@Override
public Boolean convertToEntityAttribute(String value) {
    if (value == null) return null;
    else if (value.equals("Y")) return true;
    else if (value.equals("N")) return false;
    else throw new IllegalStateException("Invalid boolean character: " + value);
    }

还有另一种选择,如果你想在Java中允许,但不在数据库中:null

@Override
public String convertToDatabaseColumn(Boolean value) {
    if (value == null) return "-";
    else return value ? "Y" : "N";
    }

@Override
public Boolean convertToEntityAttribute(String value) {
    if (value.equals("-") return null;
    else if (value.equals("Y")) return true;
    else if (value.equals("N")) return false;
    else throw new IllegalStateException("Invalid boolean character: " + value);
    }

推荐