将OneToMany分享给他人的最佳做法是什么?

时间:2018-05-03 04:57:11

标签: jpa entity-relationship

假设我的桌子看起来像这样。

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表中吗?

1 个答案:

答案 0 :(得分:0)

就个人而言,我会尽量保持简单。

当前的映射,即:

@Entity
class Some {

    @OneToMany
    private List<Property> properties;
}

创建一个连接表,用于链接SOMEPROPERTY中的行。 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字段)。