Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Hibernate 嵌套的ID类需要像关系一样命名,即使不是派生标识符?_Hibernate_Jpa_Eclipselink_Openjpa_Datanucleus - Fatal编程技术网

Hibernate 嵌套的ID类需要像关系一样命名,即使不是派生标识符?

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

在《JavaEE8中的ProJPA2》一书的第10章中,有一节叫做“多映射属性”,其中有一个著名的部门项目示例,使用
@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
注释引入一个新术语。感谢您的澄清。