如何让 JPA 在 OneToMany
关系的 Many
端强制执行复合唯一约束的唯一值?
在下面的代码中,我有一个 Person
实体,它有一个内部 id
,并且还有一组外部复合 orgids
,用于识别患者
与其他组织的关系。这些外部复合 ID 由一个用于标识特定组织
的root
组件和一个用于标识由root
标识的特定组织
内的人
组件组成。因此,root
/extension
的组合在与每个 person
关联的 orgids
集中必须是唯一的。我该如何设置代码来完成此任务?
下面的代码不断尝试在 person_org_id 表
中插入冗余的 root
/extension
值,尽管 MySQL 数据库由于下面 DDL 中的 Unique 约束而拒绝这些插入尝试。
@Entity
@Table(name = "person")
public class Person {
@Id
@Column(name = "id")
public Integer id;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "person")
private Set<PersonID> orgids;
//other properties, then
//getters and setters
}
@Entity
@Table(name = "person_org_id",
uniqueConstraints={@UniqueConstraint(columnNames = {"id_root", "id_extension"})})
public class PersonID {
@Id
@Column(name = "id")
public int id;
@ManyToOne
@JoinColumn(name = "person_id")
private Person person;
@NotNull
@ManyToOne
@JoinColumn(name="id_root")
private Organization org;
@NotNull
@Column(name="id_extension")
private String orgpersonid;
//getters and setters
}
CREATE TABLE IF NOT EXISTS person(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY
# , other fields
)engine=InnoDB;SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS person_org_id(
id int(11) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
person_id int(11) UNSIGNED NOT NULL,
id_root varchar(100),
id_extension varchar(100),
CONSTRAINT UniqueRootExtKey UNIQUE (id_root, id_extension),
FOREIGN KEY (person_id) REFERENCES person(id),
FOREIGN KEY (id_root) REFERENCES organization(root)
)engine=InnoDB;SHOW WARNINGS;
CREATE TABLE IF NOT EXISTS organization(
root varchar(100) NOT NULL PRIMARY KEY,
name varchar(200)
)engine=InnoDB;SHOW WARNINGS;
这是在使用 hibernate 和 jpa 的 spring mvc 应用程序中。
最佳答案
本质上,PersonID 表本身并不是一个实体,而是个人和组织之间的链接表。您可以将此关联映射为 Hibernate/JPA 中的映射,使用(在人员方面)组织作为键,使用扩展名作为值。 (您也可以在组织端映射,并以扩展名作为键)
但是,维护 PersonID 表上的 PK 会很困难。然而,这个字段似乎是多余的。您可以删除它并添加通常在 Map 映射表上使用的约束。
就您而言,我将创建一个类结构,其中 person 具有 Map
或者,您可以将 PersonID 维护为实体,它存储在映射中,并使用双向关联回 Person,并在 Map
关于java - OneToMany 关系中的复合唯一约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25125022/