【发布时间】:2014-09-27 07:13:40
【问题描述】:
如何让 JPA 在 OneToMany 关系的 Many 一侧强制执行复合唯一约束的唯一值?
在下面的代码中,我有一个Person 实体,它有一个内部id,还有一组外部复合orgids,用于识别patient 与其他组织的关系.这些外部复合 id 由一个 root 组件和一个 extension 组件组成,该组件标识特定的 organization,该组件标识由 root 标识的特定 organization 内的 person。因此,root/extension 的组合在与每个person 关联的orgids 集合中必须是唯一的。如何设置代码来完成此操作?
下面的代码不断尝试在person_org_id table 中插入冗余的root/extension 值,尽管由于下面的 DDL 中的唯一约束,MySQL 数据库拒绝了这些插入尝试。
@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 应用程序。
【问题讨论】:
-
我承认我的 JPA 有点生疏了(在我当前的长期项目中,我们只使用 JDBC
CallableStatements 来对抗存储过程),但你不想要OneToOne关系吗?不过,也许我只是误读了这个问题。 -
@Powerlord 在
OneToOne关系中仍然允许Set或orgids吗?person将在其orgids集中有多个条目,但orgids集中的每个成员必须是root/extension的唯一组合,以反映多个不同的organizations,每个都有自己唯一的复合标识符用于相同的person。
标签: java spring hibernate spring-mvc jpa