带枚举的Hibernate查找表

带枚举的Hibernate查找表,hibernate,enums,lookup-tables,Hibernate,Enums,Lookup Tables,我目前正在尝试学习hibernate,遇到了一个从OOP和DB的角度来看都合理的问题,但我无法找到解决方案 我的java部件大致如下所示: @Entity @Table (name = "Vehicles") class Vehicle { @Id @Column (name = "UUID") UUID id; VehicleType type (getters, setters, other values, etc.) } enum Vehicl

我目前正在尝试学习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;
}
@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
}
my DB part有两个表-一个用于车辆,另一个用于车辆类型的查找表:

车辆

UUID VARCHAR (PK)
vehicle_type_id INT (FK to VehicleTypes)
vehicle_type_id INT (PK)
vehicle_type VARCHAR
车辆类型

UUID VARCHAR (PK)
vehicle_type_id INT (FK to VehicleTypes)
vehicle_type_id INT (PK)
vehicle_type VARCHAR
我的问题是,是否有可能以目前的方式安排?如果可能,如何实现它(注释等)。如果没有,实施类似结构的最佳方式是什么

----编辑---

我用Anthony Patricio所描述的方法实现了我的目标(或多或少)

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;
}
@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
}
此解决方案符合我的要求-车辆类型在数据库端(通过查找表限制)和java端(通过车辆类型枚举)都受到限制。此外,车辆类型存储为整数,减少了存储数据所需的空间。最后但并非最不重要的一点是,此解决方案允许非常安全地添加新车型(例如与
EnumType.ORDINAL
相关的问题)

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

您可以使用“枚举”注释

@Enumerated(EnumType.STRING)
VehicleType type 

但是我在Vehicles表中没有(也不希望有)vehicle_type列。我只有vehicle_type_id,不知道如何连接这两个数据来形成vehicle对象。vehicle_type是字符串还是属性的组合?目前它只是如上所述的枚举。我在Java端有用于类型控制的枚举。VehicleType表用于在DB侧强制执行车辆。我可以为用户提供对VehicleType表的只读访问权限,并确保不能向DB中添加新的车辆类型。我不同意,我认为这种设计是正确的,允许在int而不是string上使用属性索引。如果用户确实需要在更大的表上进行查找,则性能会更好。您永远不应该让ORM决定您的数据库结构。你能找到解决办法吗?我也有类似的问题。您可以使用序号枚举类型,但是使用数据库的任何人都必须猜测,因为没有表可确定。