2

我正在开发一个 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,但这并不能解决我的问题。

4

1 回答 1

2

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

在此处输入图像描述

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

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

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

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

也可以看看:

于 2012-09-10T11:29:21.873 回答