假设我的桌子看起来像这样。
K VARCHAR PK
V VARCHAR
它只是一个表存储键和值的条目。
现在,我希望它通常用于其他实体。
实体A具有多个属性,而实体B可以具有多个属性。
@Entity
class Property {
String key;
String value;
}
将Property
实体与其他实体共享的最佳做法是什么?
@Entity
class Some {
@OneToMany
private List<...Property> properties;
}
@Entity
class SomeOther {
@OneToMany
private List<...Property> properties;
}
我计划使用继承。
@Entity
@Inheritance
class Property {
}
我知道我可以扩展它。
@Entity
@DiscriminatorValue("SomeOther")
class SomeProperty extends Property {
}
@Entity
@DiscriminatorValue("SomeOther")
class SomeOtherProperty extends Property {
}
现在我的桌子应该怎么样?
我应该创建SOME_PROPERTY
表吗?
或者我应该将SOME_ID
添加到PROPERTY
表中吗?
答案 0 :(得分:0)
就个人而言,我会尽量保持简单。
当前的映射,即:
@Entity
class Some {
@OneToMany
private List<Property> properties;
}
创建一个连接表,用于链接SOME
和PROPERTY
中的行。 InheritanceType.JOINED
你几乎一样。
如果稍微修改映射:
@Entity
class Some {
@OneToMany
@JoinColumn
private List<Property> properties;
}
你最终会在PROPERTY
中指向SOME
的外键(并且为SomeOther
重复使用此映射将导致另一个外键)。 InheritanceType.SINGLE_TABLE
你几乎一样。
在这里使用继承只会使事情复杂化。我会选择上面的一个选项,或使用更简单的映射:
@Entity
public class Some {
@ElementCollection
@MapKeyColumn(name = "K")
@Column(name = "V")
@CollectionTable(name = "PROPERTY", joinColumns = @JoinColumn(name = "some_id"))
private Map<String, String> properties;
}
以上将属性表示为Map<String, String>
,这就是它们的真实含义。唯一的缺点是,当您重用此映射(仅更改连接列名称,例如some_other_id
)时,您的JPA提供程序可能难以生成架构。当然,您可以决定将不同实体的属性分开,在这种情况下,您可以更改集合表名称(然后您将获得等效的Inheritance.TABLE_PER_CLASS
)。
BTW我认为K
作为主键是不合理的,假设密钥将针对Some
的不同实例重复。如果您使用@OneToMany
决定其中一个解决方案,我建议您向@Id @GeneratedValue Long id
实体添加代理键(Property
字段)。