【发布时间】:2015-05-11 13:13:33
【问题描述】:
我有一个“标记”机制(有点像 Gmail 的标签),为了这个问题,我想用它标记另一个实体 - 员工。
Tag 实体很简单,只包含名称,如下所示:
@Entity
public class Tag implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "tag_id", unique = true, nullable = false)
private Long id;
@Column(name = "name", unique = true)
private String name;
@ManyToMany(fetch = FetchType.LAZY, mappedBy = "tags")
private Set<Employee> employees = new HashSet<>(0);
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public Set<Employee> getEmployees() {
return employees;
}
}
我的 Employee 实体如下所示:
@Entity
public class Employee implements Serializable {
private static final long serialVersionUID = -6809049173391335091L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "employee_id", unique = true, nullable = false)
private Long id;
@Column
private String name;
@Column
private String description;
@Column
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
@JoinTable(name = "employee_tag", joinColumns = {
@JoinColumn(name = "employee_id", nullable = false, updatable = false) },
inverseJoinColumns = { @JoinColumn(name = "tag_id",
nullable = false, updatable = false) })
private List<Tag> tags = new ArrayList<>();
// Rest of Getters and Setters
public List<Tag> getTags() {
return tags;
}
public void setTagsFromString(final String tags) {
String[] realTagsSplitted = tags.split(",");
for(String tagString: realTagsSplitted) {
Tag tag = new Tag();
tag.setName(tagString);
this.tags.add(tag);
}
}
我想做的是能够从 UI 标记添加到 Employee 实体。但标签是 UI 中的纯字符串。我希望当 Employee 实体被持久化以使标签也被持久化时 BUT 我不希望标签表中出现重复(通过重复我,当然,意味着不应该存在两个标签名称相同但 id 不同)。
含义 - 如果表中存在标签“Tag1”而标签“Tag2”不存在,并且用户在 UI 中将“Tag1”和“Tag2”都添加到员工“Employee1”我想:
- 在连接表中创建一个新行,将“Employee1”的 id 绑定到“Tag1”的 id。
- 使用“Tag2”在 Tag 表中创建一个新行
- 在连接表中创建一个新行,将“Employee1”的 id 绑定到新创建的“Tag2”的 id。
我真的更喜欢在代码级别处理它,如果存在解决方案,最好使用注释。我试图避免 DB 触发器和阅读代码时不明显的事情。
【问题讨论】:
标签: java spring entity-framework hibernate jpa