类型,属性,实例和值之间的关系

时间:2012-09-10 11:01:02

标签: java hibernate database-design

我正在开发一个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-&gt; Attribute-&gt; Type和AttributeValue-&gt; Instance-&gt; Type

来访问类型

另一个想法是使用type + attribute name作为属性的id,使用instance + attribute name作为属性值的id,但这并不能解决我的问题。

1 个答案:

答案 0 :(得分:2)

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

enter image description here

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

请注意我们如何从钻石顶部迁移 {/ 1}},从两侧向下,一直到底部,然后合并。因此,由于只有一个TYPE_ID字段并且涉及两个FK,我们永远不会有属性类型的类型与实例类型不同的属性实例。

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

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

另见: