来自具有属性访问权的外键的JPA复合主键
我是JPA的新手,请留在我身边。
显然,如何以属性访问方式从外键创建组合主键是没有问题的。
题
如果我按照下面的示例使用属性访问类型,那么是否还必须为引用的FK定义getter和setters?
我不认为这是事实,但Java EE6的官方文档是这样做的。
适用于J2EE的Oracle®容器Enterprise JavaBeans开发人员指南
复合主键类具有以下特征:
您可以使复合主键类为实体类拥有的嵌入类,或者将其映射到实体类的多个字段或属性的非嵌入类。 在后一种情况下,组合主键类中的主键字段或属性的名称与实体类的名称必须一致,且它们的类型必须相同。
我修改了这个例子,因为我想使用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;
}
}
上一篇: JPA composite primary key from foreign keys with property access