Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.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
Java 来自具有属性访问的外键的JPA复合主键_Java_Jpa_Eclipselink - Fatal编程技术网

Java 来自具有属性访问的外键的JPA复合主键

Java 来自具有属性访问的外键的JPA复合主键,java,jpa,eclipselink,Java,Jpa,Eclipselink,我是JPA新手,请留下来。 显然,如何以属性访问方式从外键创建复合主键是毫无疑问的 问题 如果我像下面的例子一样使用属性访问类型,我是否也必须为引用的FK定义getter和setter 我认为情况并非如此,但JavaEE6的应用程序确实如此 复合主键类具有以下特征: 这是一门POJO课程 它必须是公共的,并且必须有一个公共的无参数构造函数 如果使用基于属性的访问,主键类的属性必须是公共的或受保护的。 它必须是可序列化的 它必须定义equals和hashCode方法 这些方法的值相等的语义必须

我是JPA新手,请留下来。

显然,如何以属性访问方式从外键创建复合主键是毫无疑问的

问题

如果我像下面的例子一样使用属性访问类型,我是否也必须为引用的FK定义getter和setter

我认为情况并非如此,但JavaEE6的应用程序确实如此

复合主键类具有以下特征:

  • 这是一门POJO课程
  • 它必须是公共的,并且必须有一个公共的无参数构造函数
  • 如果使用基于属性的访问,主键类的属性必须是公共的或受保护的。
  • 它必须是可序列化的
  • 它必须定义equals和hashCode方法
  • 这些方法的值相等的语义必须与键映射到的数据库类型的数据库相等一致
您可以将复合主键类设置为嵌入类或 由实体类或映射其字段的非嵌入类拥有 指向实体类的多个字段或属性。在后者 大小写组合中主键字段或属性的名称 主键类和实体类的主键类必须对应且 它们的类型必须相同

我修改了这个示例,因为我想使用FKs

Example 7-2 Embeddable Composite Primary Key Class

@Embeddable
public class EmployeePK implements Serializable {
    private String name;
    private long id;

    public EmployeePK() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public int hashCode() {
        return (int) name.hashCode() + id;
    }

    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof EmployeePK)) return false;
        if (obj == null) return false;
        EmployeePK pk = (EmployeePK) obj;
        return pk.id == id && pk.name.equals(name);
    }
}

Example 7-3 JPA Entity With an Embedded Composite Primary Key Class

@Entity
@Access(AccessType.PROPERTY)
public class Employee implements Serializable {
    EmployeePK primaryKey;
 
    public Employee() {
    }
 
    @EmbeddedId
    public EmployeePK getPrimaryKey() {
        return primaryKey;
    }
 
    public void setPrimaryKey(EmployeePK pk) {
        primaryKey = pk;
    }
 
    @ManyToOne
    @MapsId("id")
    private classWithPKid fkobject1;

    @ManyToOne
    @MapsId("name")
    private classWithPKname fkobject2;
    ...
}
JPA规范(2.3.2)-显式访问类型 当访问(属性)应用于实体类、映射超类或可嵌入类时,可以在该类的属性上放置映射注释,持久性提供程序运行时通过该类定义的属性访问持久性状态。所有未使用瞬态注释进行注释的属性都是持久的。当访问(属性)应用于此类类时,可以有选择地指定类内的单个属性作为实例变量访问要指定持久性提供程序运行时访问的持久性实例变量,必须将该实例变量指定为访问(字段)如果在未指定访问权限(字段)的类定义的任何实例变量上放置映射注释,则该行为未定义。从超类继承的持久状态根据这些超类的访问类型进行访问

JPA规范(2.3.3)-可嵌入类的访问类型 可嵌入类的访问类型由实体类、映射超类或嵌入该类的可嵌入类
(包括作为元素集合的成员)的访问类型决定,而与包含类的访问类型是否已明确指定或默认无关。通过如上所述的访问注释,可以为可嵌入类指定不同的访问类型

当实体类的AccessType设置为PROPERTY时,提供程序将使用这些方法获取持久状态和映射数据。当类的AccessType为PROPERTY时,持久性提供程序没有义务在字段上查找映射注释。另外,请注意,AccessType是由嵌入式类继承的,这就是EmployeePK也需要定义getter/setter的原因。根据规范中的说明,当实体类使用Access(PROPERTY)时,应执行以下操作之一:

  • 为FK字段定义getter/setter方法,并将映射放在getter方法上

    例如:

    @Entity
    @Access(AccessType.PROPERTY)
    public class Employee {
        private EmployeePK primaryKey;
    
        private ClassWithPKid fkobject1;
    
        @EmbeddedId
        public EmployeePK getPrimaryKey() {
            return primaryKey;
        }
    
        @ManyToOne
        @MapsId("id")
        public ClassWithPKid getFkobject1() {
            return fkobject1;
        }
    }
    
    @Entity
    @Access(AccessType.PROPERTY)
    public class Employee {
        private EmployeePK primaryKey;
    
        @ManyToOne
        @MapsId("id")
        @Access(AccessType.FIELD)
        private ClassWithPKid fkobject1;
    
        @EmbeddedId
        public EmployeePK getPrimaryKey() {
            return primaryKey;
        }
    }
    
  • 或者,在持久字段上显式定义访问(字段)

    例如:

    @Entity
    @Access(AccessType.PROPERTY)
    public class Employee {
        private EmployeePK primaryKey;
    
        private ClassWithPKid fkobject1;
    
        @EmbeddedId
        public EmployeePK getPrimaryKey() {
            return primaryKey;
        }
    
        @ManyToOne
        @MapsId("id")
        public ClassWithPKid getFkobject1() {
            return fkobject1;
        }
    }
    
    @Entity
    @Access(AccessType.PROPERTY)
    public class Employee {
        private EmployeePK primaryKey;
    
        @ManyToOne
        @MapsId("id")
        @Access(AccessType.FIELD)
        private ClassWithPKid fkobject1;
    
        @EmbeddedId
        public EmployeePK getPrimaryKey() {
            return primaryKey;
        }
    }
    

  • 有些事情看起来不太对劲,但它并不是“得者”和“设者”——根据经验,你可以假设在JPA中,一切都需要这些。请将您的所有实体添加到问题中。以上修改的示例是否足够?您的问题很难回答。第一个问题很混乱,第二个问题可能有不止一个答案。试试看!如果你有一个明确的成功标准的具体问题(比如“答案解释了如何使它工作,而它以前没有”),这个网站工作得最好。好的,我将尝试只定义一个明确的问题。你的代码工作吗?最好的方法就是运行它并发布异常。而且规格看起来很清楚-你所拥有的应该有用。MapsId与ID注释非常不同——您只是告诉JPA这两个映射在下面使用相同的字段。你也可以不用你的嵌入式ID,只需将多个one映射标记为ID字段,而使用你的嵌入式类作为pk类。同时,我使用了示例一,多亏了你,我现在确信这是正确的,到目前为止,eclipse link 2.5和JPA 2.0没有错误(尽管只是一个初始测试)。此外,由于accessType是继承的,我不需要将accessType.PROPERTY放在可嵌入PK类的上方,对吗?@MADforFUNandHappy正确。可嵌入类的访问类型由其嵌入的实体类的访问类型确定。您不需要在可嵌入类上显式定义它。