代码之家  ›  专栏  ›  技术社区  ›  Kawu

JPA 1.0使用带有*嵌套*复合主键的@IdClass的限制?

  •  1
  • Kawu  · 技术社区  · 14 年前

    部门具有以下属性(组合主键):

    @Entity
    @IdClass(DeptId.class)
    public class Department
    {
        @Id
        @Column(name="number")
        private Integer number;
    
        @Id
        @Column(name="country")
        private String country;
    
        @Column(name="name")
        private String name;
    
        @OneToMany(mappedBy="dept")
        private Collection<Project> projects;
    
        ...
    }
    

    这里是PK类:

    public class DeptId implements Serializable
    {
        private Integer number;
        private String country;
    
        ...
    }
    

    那么(有问题的)JPA 1.0@IdClass实现必须看起来像那样(冗余的deptNum和depttry属性):->它只是一个部门内的唯一名称

    @Entity 
    @IdClass(ProjectId.class)
    public class Project
    {
        @Id
        @Column(name="dept_number")
        private Integer deptNumber;
    
        @Id
        @Column(name="dept_country")
        private String deptCountry;
    
        @Id
        @Column(name="name")
        private String name;
    
        @ManyToOne 
        @JoinColumns({
           @JoinColumn(name="dept_number", referencedColumnName="number"),
           @JoinColumn(name="dept_country", referencedColumnName="country")
        })    
        private Department dept;
    
        ...
    }
    

    public class ProjectId implements Serializable
    {
        private String name;
        private DeptId dept;
    
        ...
    }
    

    问题是Hibernate和EclipseLink都不知道如何将Project中的两个冗余属性deptNum和deptCtry映射到DeptId中的dept属性(或其中的属性)。->映射异常等。

    这是否是JPA 1.0的一个限制,即具有组合键的表引用了具有@IdClass实现的其他组合键 ,因为JPA实现根本不知道如何映射这些字段?

    谢谢

    3 回复  |  直到 14 年前
        1
  •  3
  •   Chris    14 年前

    这个模型可以通过使用JPA2.0@MapsId重用,它还将使用关系中的值为您维护基本映射。我看到的唯一好处是,您不需要访问关系(可能会导致不必要的连接或对惰性关系的数据库访问)来获取外键/id字段值。

    至于zip are a eclipseelink异常,它们是由于ZipAreaId具有ZipId zip属性,而不是被展平。JPA 1.0要求key类对于实体中的每个@ID属性具有相同类型和名称的属性。

        2
  •  2
  •   Pascal Thivent    14 年前

    问题是冬眠和日食线都不知道如何映射这两者 冗余 项目中的属性deptNum和depttry到DeptId中的dept属性

    这就是为什么你需要定义 ManyToOne 外键为 只读 用这种映射。这是通过设置 JoinColumn 属性 insertable updatable false .

    因此,请尝试以下操作:

    @Entity 
    @IdClass(ProjectId.class)
    public class Project
    {
        @Id
        @Column(name="dept_number")
        private Integer deptNumber;
    
        @Id
        @Column(name="dept_country")
        private String deptCountry;
    
        @Id
        @Column(name="name")
        private String name;
    
        @ManyToOne 
        @JoinColumns({
           @JoinColumn(name="dept_number", referencedColumnName="number", insertable=false, updatable=false),
           @JoinColumn(name="dept_country", referencedColumnName="country", insertable=false, updatable=false)
        })    
        private Department dept;
        ...
    }
    
        3
  •  2
  •   Kawu    14 年前

    所发布代码的问题是,JPA 1.0实际上不允许嵌套复合主键类。此项目ID无效:

    public class ProjectId implements Serializable
    {
        private String name;
        private DeptId dept;
    
        ...
    }
    

    public class ProjectId implements Serializable
    {
        private Integer deptNumber;
        private String deptCountry;
        private String name;
    
        ...
    }
    

    我刚刚有一个日食的版本,但Hibernate有问题。我想知道如何告诉Hibernate假设JPA 1.0。