【问题标题】:Relation between type, attribute, instance and value类型、属性、实例和值之间的关系
【发布时间】:2012-09-03 05:41:47
【问题描述】:

我正在开发一个 Java 应用程序,它通过 Hibernate 将其数据存储在数据库中。

此应用程序的一个功能是定义模板(如类型等)以供重用。例如,类型具有属性,您可以创建具有属性值的类型的实例。

问题是,我不知道如何确保只能分配类型定义的属性值。在我的解决方案中存在导致问题的冗余,但我不知道如何删除它。

我目前的(和有问题的)方法如下所示:

@Entity
class Type
{
    @Id
    @Generated
    private Long id;

    @OneToMany(mappedBy="type")
    private List<Attribute> attributes;

    //...
}

@Entity
class Attribute
{
    @Id
    @Generated
    private Long id;

    @ManyToOne
    private Type type;

    //...
}

@Entity
class Instance
{
    @Id
    @Generated
    private Long id;

    @ManyToOne
    private Type type;

    //...
}

@Entity
class AttributeValue
{

    @Id
    @Embedded
    private ResourceAttributValueId id;

    @Column(name="val")
    private String value;

    //...
}

@Embeddable
public class ResourceAttributValueId implements Serializable
{
    @ManyToOne
    private ResourceStateImpl resource;

    @ManyToOne
    private ResourceAttributeImpl attribute;

    //...
}

这里类型的定义是多余的:类型可以通过AttributeValue->Attribute->Type和AttributeValue->Instance->Type得到

另一个想法是使用类型+属性名称作为属性的id,使用实例+属性名称作为属性值的id,但这并不能解决我的问题。

【问题讨论】:

    标签: java hibernate database-design


    【解决方案1】:

    像这样正确建模“菱形”依赖关系的关键是识别关系的使用:

    (我冒昧地稍微重命名了您的实体,我认为这是一个更一致的命名方案。)

    注意我们如何迁移 TYPE_ID 从菱形的顶部,从两侧向下,一直到底部,然后在此处合并。因此,由于只有一个ATTRIBUTE_INSTANCE.TYPE_ID 字段并且在两个FK 中都涉及,因此我们永远不会有一个属性类型的类型与实例类型不同的属性实例。

    虽然这避免了“不匹配”属性,但它仍然不能确保属性实例的存在(如果您支持“必需属性”的概念),最好在应用程序级别执行.从理论上讲,您可以使用循环延迟 FK 在数据库级别强制执行它,但并非所有 DBMS 都支持它,我怀疑它是否能很好地与 ORM 配合使用。

    不幸的是,我没有足够的 Hibernate 经验来回答是否可以将其映射到那里以及如何映射。

    另见:

    【讨论】:

    • 迁移和合并主键似乎是此类问题在数据库级别的解决方案。老实说,自从我使用 Hibernate 以来,我已经忘记了选择正确主键的能力。事实上,Hibernate 目前不支持使用“重叠”外键,所以我花了一些时间才找到 Hibernate 接受并且不太“脏”的解决方案。如果有人对它感兴趣,我会发布它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 2021-10-07
    • 2021-09-25
    • 2013-03-27
    • 2022-12-06
    • 1970-01-01
    相关资源
    最近更新 更多