繁体   English   中英

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

[英]JPA composite primary key from foreign keys with property access

我是JPA的新手,请和我在一起。

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

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

我认为情况并非如此,但Java EE6的官方文档确实如此。

Oracle®J2EE企业版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)应用于实体类 ,映射的超类或可嵌入的类时,映射注释可以放在该类的属性上,并且持久性提供程序运行时会通过该类定义的属性访问持久状态 未使用Transient批注进行批注的所有属性都是持久性的。 将Access(PROPERTY)应用于此类时,可以有选择地在该类中指定各个属性,例如变量访问。 要指定持久性实例变量以供持久性提供程序运行时访问,必须将该实例变量指定为Access(FIELD) 如果将映射批注放置在未为其指定Access(FIELD)的类定义的任何实例变量上,则该行为未定义 从超类继承的持久状态将根据这些超类的访问类型进行访问。

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

可嵌入类的访问类型取决于实体类 ,映射超类或嵌入 的可嵌入类的访问类型 (包括作为元素集合的成员),而与包含类的访问类型是否具有已明确指定或默认。 可以通过如上所述的Access注释为该可嵌入类指定不同的可嵌入类访问类型。

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

  1. 为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; } } 
  2. 或者,在持久字段上显式定义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; } } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM