java类型、属性、实例和值之间的关系
我正在开发一个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->;属性->;类型和属性值->;实例->;类型
另一个想法是使用类型+属性名作为属性的id,使用实例+属性名作为属性值的id,但这并不能解决我的问题
# 1 楼答案
正确建模“菱形”依赖关系的关键是识别关系:
(我冒昧地对您的实体稍加重命名,我认为这是一个更一致的命名方案。)
请注意,我们是如何将
TYPE_ID
从钻石的顶部、两侧向下,一直移动到底部,然后将其合并到那里的。因此,由于只有一个ATTRIBUTE_INSTANCE.TYPE_ID
字段,并且这两个FK都涉及到它,所以我们永远不可能有一个属性类型与实例类型不同的属性实例虽然这避免了“不匹配”属性,但它仍然不能确保属性实例的存在(如果您支持“必需属性”的概念),这最好在应用程序级别实施。理论上,您可以在数据库级别使用循环延迟FKs来实施它,但并不是所有DBMS都支持这一点,我怀疑它是否能很好地与ORMs配合使用
不幸的是,我对Hibernate没有足够的经验来回答它是否可以映射到那里以及如何映射
另见: