以多个外键作为复合主键的一对多实体映射
Entity mapping for one to many with multiple foreign keys as composite primary key
我浏览了 java 持久性文档和大量关于这种表示的 Whosebug 示例。有人可以验证我这样做是否正确吗?
类型 A 的实例与类型 C 的许多实例相关联。类型 B 的实例与类型 C 的许多实例相关联。C 的实例具有复合主键,该主键包含指向实体 a 和B.
表格:
一个
|------|
| A_ID |
|------|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
|------|
其中A_ID是主键
B
|------|
| B_ID |
|------|
| 1 |
| 2 |
|------|
其中 B_ID 是主键
C
|------|------|
| A_ID | B_ID |
|------|------|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
|------|------|
其中外键组合(A_ID、B_ID)为主键
实体:
@Entity
Class A {
@Id
@PrimaryKeyColumnName(name="A_ID")
private Long id;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true,
mappedBy="A_ID"
)
Collection<C> values;
public Long getId() {
return this.id;
}
public Collection<C> getValues() {
return this.values;
}
}
@Entity
Class B {
@Id
@PrimaryKeyColumnName(name="B_ID")
private Long id;
public Long getId() {
return this.id;
}
}
@Entity
Class C {
@EmbeddedId
private CId cId;
public CId getCId() {
return this.cId;
}
}
@Embeddable
Class CId {
@ManyToOne
@JoinColumn(name="A_ID")
private A a;
@ManyToOne
@JoinColumn(name="B_ID")
private B b;
public Long getA() {
return this.a;
}
public Long getBId() {
return this.b;
}
@Override
public int hashCode() {
return Objects.hash(
this.getA().getId(),
this.getBId().getId()
);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof CId)) return false;
CId that = (CId) obj;
return Objects.equals(this.getA().getId(),
that.getA().getId()) &&
Objects.equals(this.getBId().getId(),
that.getBId().getId());
}
}
这就是 JPA 规范所说的 "derived identity"。你应该稍微不同地定义你的 类 。以下是代码的重要部分:
@Entity
Class A {
@Id
@Column(name="A_ID")
private Long id;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true,
mappedBy="a"
)
Collection<C> values;
...
}
@Entity
Class B {
@Id
@Column(name="B_ID")
private Long id;
...
}
@Entity
Class C {
@EmbeddedId
private CId cId;
@ManyToOne
@JoinColumn(name="A_ID")
@MapsId("aId") // maps aId attribute of embedded id
private A a;
@ManyToOne
@JoinColumn(name="B_ID")
@MapsId("bId") // maps bId attribute of embedded id
private B b;
...
}
@Embeddable
Class CId {
private Long aId; // corresponds to PK type of A
private Long bId; // corresponds to PK type of B
...
}
派生身份在 JPA 2.1 规范的第 2.4.1 节中进行了讨论。
我浏览了 java 持久性文档和大量关于这种表示的 Whosebug 示例。有人可以验证我这样做是否正确吗?
类型 A 的实例与类型 C 的许多实例相关联。类型 B 的实例与类型 C 的许多实例相关联。C 的实例具有复合主键,该主键包含指向实体 a 和B.
表格:
一个
|------|
| A_ID |
|------|
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
|------|
其中A_ID是主键
B
|------|
| B_ID |
|------|
| 1 |
| 2 |
|------|
其中 B_ID 是主键
C
|------|------|
| A_ID | B_ID |
|------|------|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
|------|------|
其中外键组合(A_ID、B_ID)为主键
实体:
@Entity
Class A {
@Id
@PrimaryKeyColumnName(name="A_ID")
private Long id;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true,
mappedBy="A_ID"
)
Collection<C> values;
public Long getId() {
return this.id;
}
public Collection<C> getValues() {
return this.values;
}
}
@Entity
Class B {
@Id
@PrimaryKeyColumnName(name="B_ID")
private Long id;
public Long getId() {
return this.id;
}
}
@Entity
Class C {
@EmbeddedId
private CId cId;
public CId getCId() {
return this.cId;
}
}
@Embeddable
Class CId {
@ManyToOne
@JoinColumn(name="A_ID")
private A a;
@ManyToOne
@JoinColumn(name="B_ID")
private B b;
public Long getA() {
return this.a;
}
public Long getBId() {
return this.b;
}
@Override
public int hashCode() {
return Objects.hash(
this.getA().getId(),
this.getBId().getId()
);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof CId)) return false;
CId that = (CId) obj;
return Objects.equals(this.getA().getId(),
that.getA().getId()) &&
Objects.equals(this.getBId().getId(),
that.getBId().getId());
}
}
这就是 JPA 规范所说的 "derived identity"。你应该稍微不同地定义你的 类 。以下是代码的重要部分:
@Entity
Class A {
@Id
@Column(name="A_ID")
private Long id;
@OneToMany(
cascade = CascadeType.ALL,
orphanRemoval = true,
mappedBy="a"
)
Collection<C> values;
...
}
@Entity
Class B {
@Id
@Column(name="B_ID")
private Long id;
...
}
@Entity
Class C {
@EmbeddedId
private CId cId;
@ManyToOne
@JoinColumn(name="A_ID")
@MapsId("aId") // maps aId attribute of embedded id
private A a;
@ManyToOne
@JoinColumn(name="B_ID")
@MapsId("bId") // maps bId attribute of embedded id
private B b;
...
}
@Embeddable
Class CId {
private Long aId; // corresponds to PK type of A
private Long bId; // corresponds to PK type of B
...
}
派生身份在 JPA 2.1 规范的第 2.4.1 节中进行了讨论。