【问题标题】:Hibernate lookup table with enum带有枚举的休眠查找表
【发布时间】:2023-03-03 06:30:20
【问题描述】:

我目前正在尝试学习 hibernate,遇到了一个从 OOP 和 DB 角度来看都合理的问题,但我无法找到解决方案。

我的 java 部分或多或少是这样的:

@Entity
@Table (name = "Vehicles")
class Vehicle {
    @Id
    @Column (name = "UUID")
    UUID id; 
    VehicleType type

    (getters, setters, other values, etc.)
}

enum VehicleType {
    TRUCK,
    TRAILER,
    OTHER;
}

我的数据库部分有两个表 - 一个用于车辆,一个用于车辆类型的查找表:

车辆

UUID VARCHAR (PK)
vehicle_type_id INT (FK to VehicleTypes)

车辆类型

vehicle_type_id INT (PK)
vehicle_type VARCHAR

我的问题是,是否可以按照所介绍的方式进行安排?如果可能,如何实现它(注释等)。如果没有,实现类似结构的最佳方法是什么?

-----编辑-----

使用 Anthony Patricio 描述的 solution,我已经成功实现了我的目标(或多或少)。

DB 部分保持不变,而 Java 部分如下所示:

@Entity
@Table (name = "Vehicles")
class Vehicle {
    @Id
    @Column (name = "UUID")
    UUID id;
    @Column (name = "vehicle_type_id")
    @Type (type = "VehicleEnumUserType")
    VehicleType type

    (getters, setters, other values, etc.)
}

enum VehicleType {
    TRUCK(1),
    TRAILER(2),
    OTHER(0);

    private int value;
    VehicleType(int value){
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public static VehicleType fromValue(int value){
        for (VehicleType type : VehicleType.values()){
            if (value == type.value) return type;
        }
        throw new IllegalArgumentException("Value not mapped by VehicleType enum");
    }
}

VehicleEnumUserType implements UserType{
    private static final int[] SQL_TYPES = {Types.INTEGER};

    public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sharedSessionContractImplementor, Object o)
            throws HibernateException, SQLException {
        int number = resultSet.getInt(strings[0]);
        return resultSet.wasNull() ? null : VehicleType.fromValue(number);
    }

    public void nullSafeSet(PreparedStatement preparedStatement, Object o, int i, SharedSessionContractImplementor sharedSessionContractImplementor)
            throws HibernateException, SQLException {
        if (o == null){
            preparedStatement.setNull(i, Types.INTEGER);
        } else {
            preparedStatement.setInt(i, ((VehicleType)o).getValue());
        }
    }
    // other mandatory methods required by UserType interface
}

此解决方案符合我的要求 - 车辆类型在 DB 端(通过查找表限制)和 Java 端(通过 VehicleType 枚举)都受到限制。此外,车辆类型以整数形式存储,减少了存储数据所需的空间。最后但同样重要的是,此解决方案允许非常安全地添加新车辆类型(例如与 EnumType.ORDINAL 相关的问题)。

希望任何人都觉得这个解决方案有用。

【问题讨论】:

    标签: hibernate enums lookup-tables


    【解决方案1】:

    你可以使用“枚举”注解

    @Enumerated(EnumType.STRING)
    VehicleType type 
    

    【讨论】:

    • 但我在 Vehicles 表中没有(而且我不想有)vehicle_type 列。我只有vehicle_type_id,不知道如何将这两条数据连接起来形成Vehicle对象。
    • vehicle_type 是字符串还是属性组合?
    • 目前它只是上面介绍的枚举。
    • 我在 Java 端有用于类型控制的枚举。 VehicleType 表用于在 DB 端执行 velue。我可以为用户授予对 VehicleType 表的只读访问权限,并确保不能将新的车辆类型添加到数据库中。
    • 我不同意,我认为如果他确实需要在更大的表上进行查找,则允许在 int 上而不是字符串上使用属性索引的设计是正确的,这样性能会更高。你永远不应该让 ORM 决定你的数据库结构。你能找到解决方案吗?我有一个类似的问题。您可以使用序数枚举类型,但是使用数据库的任何人都必须猜测,因为没有要确定的表。
    猜你喜欢
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-16
    • 2012-01-17
    • 1970-01-01
    相关资源
    最近更新 更多