我应该使用哪个注释:@IdClass或@EmbeddedId

(Java Persistence API) 规范有 2 种不同的方法来指定实体复合键:和 。JPA@IdClass@EmbeddedId

我在映射的实体上使用了这两个注释,但对于不太熟悉的人来说,这是一个很大的混乱。JPA

我只想采用一种方法来指定复合键。哪一个真的是最好的?为什么?


答案 1

我认为这可能更详细,因为您无法使用任何字段访问运算符访问整个主键对象。使用 你可以这样做:@EmbeddedId@IdClass@EmbeddedId

@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
  @EmbeddedId EmployeeId employeeId;
  ...
}

这给出了构成复合键的字段的清晰概念,因为它们都聚合在通过字段访问运算符访问的类中。

与和的另一个区别是当涉及到编写HQL时:@IdClass@EmbeddedId

用你写:@IdClass

select e.name from Employee e

和你一起写:@EmbeddedId

select e.employeeId.name from Employee e

您必须为同一查询编写更多文本。有些人可能会争辩说,这与更自然的语言不同,例如 由 推广的语言。但大多数情况下,从查询中直接了解给定字段是复合键的一部分是无价的帮助。IdClass


答案 2

使用复合主键有三种策略:

  • 将其标记为并添加到实体类的常规属性中,并用 标记。@Embeddable@Id
  • 向实体类添加一个普通属性,并用 标记。@EmbeddedId
  • 将实体类的所有字段的属性添加到实体类中,用 标记它们,并使用 标记实体类,以提供主键类的类。@Id@IdClass

使用标记为 as 的类是最自然的方法。无论如何,该标记都可用于非主键可嵌入值。它允许您将复合主键视为单个属性,并允许在其他表中重用该类。@Id@Embeddable@Embeddable@Embeddable

下一个最自然的方法是使用标签。在这里,主键类不能在其他表中使用,因为它不是一个实体,但它确实允许我们将键视为某个类的单个属性。@EmbeddedId@Embeddable

最后,使用 和 批注,我们可以使用实体本身的属性(对应于主键类中属性的名称)来映射复合主键类。名称必须对应(没有覆盖此值的机制),并且主键类必须遵守与其他两种技术相同的义务。这种方法的唯一优点是它能够从封闭实体的接口中“隐藏”主键类的使用。批注采用 Class 类型的值参数,该参数必须是要用作复合主键的类。与要使用的主键类的属性相对应的字段都必须使用@Id进行批注。@IdClass@Id@IdClass

参考资料: http://www.apress.com/us/book/9781430228509


推荐