Hibernate 嵌套的ID类需要像关系一样命名,即使不是派生标识符?
在《JavaEE8中的ProJPA2》一书的第10章中,有一节叫做“多映射属性”,其中有一个著名的部门项目示例,使用Hibernate 嵌套的ID类需要像关系一样命名,即使不是派生标识符?,hibernate,jpa,eclipselink,openjpa,datanucleus,Hibernate,Jpa,Eclipselink,Openjpa,Datanucleus,在《JavaEE8中的ProJPA2》一书的第10章中,有一节叫做“多映射属性”,其中有一个著名的部门项目示例,使用@IdClass,完整示例代码位于 下面是一个短篇故事 项目实体: @Entity @IdClass(ProjectId.class) public class Project { @Id private String name; @Id @ManyToOne @JoinColumns({ @JoinColumn
@IdClass
,完整示例代码位于
下面是一个短篇故事
项目实体:
@Entity
@IdClass(ProjectId.class)
public class Project
{
@Id
private String name;
@Id
@ManyToOne
@JoinColumns({
@JoinColumn(name="DEPT_NUM", referencedColumnName="NUM"),
@JoinColumn(name="DEPT_CTRY", referencedColumnName="COUNTRY")
})
private Department dept;
// ...
}
项目ID类别:
public class ProjectId implements Serializable
{
private String name;
private DeptId dept; <-- named dept to conform with derived identifier naming conventions
public ProjectId() {}
public ProjectId(DeptId deptId, String name)
{
this.dept = deptId; <-- naming "mismatch"
this.name = name;
}
// ...
}
public class DeptId implements Serializable
{
private int number;
private String country;
// ...
}
部门ID类别:
public class ProjectId implements Serializable
{
private String name;
private DeptId dept; <-- named dept to conform with derived identifier naming conventions
public ProjectId() {}
public ProjectId(DeptId deptId, String name)
{
this.dept = deptId; <-- naming "mismatch"
this.name = name;
}
// ...
}
public class DeptId implements Serializable
{
private int number;
private String country;
// ...
}
这其实没什么特别的。注意ProjectId
类有一个嵌套的复合PK类字段private DeptId dept代码>
现在我的问题是
在本书后面几页的“使用EmbeddedId”一节的末尾,有一个更大的注释/小节,名为“派生标识符的替代品”,其中包含文本(你不一定需要阅读整个导语来回答问题,我只是为了完整性才发布此内容):
JPA2.0中引入了@MapsId
注释以及将@Id
应用于关系属性的能力,以改善JPA1.0中存在的情况。当时,仅使用@PrimaryKeyJoinColumn
注释指定了一对一的共享主键方案(使用Id
注释是今后首选和推荐的方法)
虽然没有特定的方法来解决在标识符中包含外键的一般情况,但通常通过添加一个或多个附加(冗余)的实践来支持字段到从属实体。每个添加的字段都将包含相关实体的外键,并且,由于添加的字段和关系都将映射到同一个联接列,因此需要将其中一个或另一个标记为只读(请参阅“只读映射”部分)下面的示例显示了清单10-17[作者不:Project
entity!]将使用JPA 1.0完成。ID类将是相同的。由于deptNumber
和deptCountry
属性是标识符属性,并且不能在数据库中更改,因此无需将其可更新性设置为false
所以,这就是“JPA1.0”的方式
ID类将是相同的
这意味着,ProjectId
ID类如上所示,但是JPA1.0不允许嵌套类
现在问题是:
对于冗余的@id
字段映射,
是什么样子的,即带有嵌套的id类?它没有按照与JPA有关的任何内容显示在书中…,而这本书很好(由知识渊博的人撰写,其中一人直接参与编写规范),如果有任何疑问,请转到规范本身进行澄清。派生ID在第2.4.1节中包含了示例,并将为您澄清。它要求ProjectId.class使用与实体中ID值相同的名称,以及与它引用的ID相同的类型-与您在DeptId中使用的格式相同。在这种情况下,它需要o应:
public class ProjectId implements Serializable
{
private String name;
private DeptId dept;
// ...
}
至于JPA1.0的用法——关于ID类的语句相同可能意味着该类的ID类需要相同的3个ID字段(和类型)与@ID注释相匹配-与此类类定义的注释相同。如果将其标记为@ID,则必须在ID类中表示它。关于这一点的混淆是JPA规范提到了“派生标识符”一点也不。这似乎是本书作者的发明。我一直认为这是一个官方术语。然而,JPA只定义了“派生身份”,这只是一个事实,即一个实体的PK依赖于另一个实体的PK,无论是否使用JPA 1.0风格的遗留映射(多个冗余的@Id
+@Column
)或JPA 2.0风格的映射(@Id
/MapsId
关于关系+可能嵌套的Id类)。这就是我理解的所谓的“派生标识符”在这本书中,由于JPA 2.0引入了后者,并且有可能在PK类中声明嵌套的复合PK类字段。也许他们试图为关系+嵌套Id类上的@Id
/@MapsId
注释引入一个新术语。感谢您的澄清。