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

我是JPA的新手,请留在我身边。

显然,如何以属性访问方式从外键创建组合主键是没有问题的。

如果我按照下面的示例使用属性访问类型,那么是否还必须为引用的FK定义getter和setters?

我不认为这是事实,但Java EE6的官方文档是这样做的。

适用于J2EE的Oracle®容器Enterprise JavaBeans开发人员指南

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

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

    我修改了这个例子,因为我想使用FK。

    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) - 显式访问类型

    当将Access(PROPERTY)应用于实体类 ,映射超类或可嵌入类时,可以将映射注释放在该类的属性上, 持久性提供程序运行时将通过该类定义的属性来访问持久状态 。 所有未使用瞬态注释注释的属性都是持久性的。 当Access(PROPERTY)应用于这样的类时,可以选择性地指定类中的各个属性以实现变量访问。 要指定持久化实例变量以供持久性提供程序运行时访问,必须将该实例变量指定为Access(FIELD)如果映射注释放置在由未指定Access(FIELD)的类定义的任何实例变量上,则行为未定义 。 根据这些超类的访问类型访问从超类继承的持久状态。

    JPA规范(2.3.3) - 可嵌入类的访问类型

    一个可嵌入类的接入类型是由实体类的接入类型 ,映射超,或可嵌入类在其所嵌入 (包括作为元素集合的成员)独立的包含类的接入类型是否已确定已明确指定或默认。 如上所述,可以通过Access注释为可嵌入类指定可嵌入类的不同访问类型。

    当AccessType设置为PROPERTY实体类时,提供程序将使用这些方法来获取持久状态和映射数据。 当类的AccessType为PROPERTY时,持久性提供程序没有义务在字段上查找映射注释。 另外请注意,AccessType由Embedded类继承,这就是为什么EmployeePK也需要定义getter / setters。 根据规范中的说法,当实体类使用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;
        }
    }
    
  • 或者,在持久字段上显式定义Access(FIELD)

    例:

    @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;
        }
    }
    
  • 链接地址: http://www.djcxy.com/p/37011.html

    上一篇: JPA composite primary key from foreign keys with property access

    下一篇: JPA JoinColumn vs mappedBy