我有一个'标签'机制(有点像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;
}
}
我的员工实体如下所示:
@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中的纯字符串。我希望当持久化员工实体时,标签仍然存在但我不想在标签表中重复(通过复制我当然意味着没有两个标签应该存在同名但不同的ID。)
含义 - 如果标签&#34; Tag1&#34;存在于表格和标签&#34; Tag2&#34;并没有在用户界面中添加&#34; Tag1&#34;和&#34; Tag2&#34;员工&#34;员工1&#34;我想:
我真的更喜欢在代码级别处理它,如果存在解决方案,最好使用注释。我试图避免数据库触发器以及通过阅读代码而不明显的事情。
答案 0 :(得分:1)
您应该在服务级别而不是实体中处理此问题。这些步骤:
findOrCreateTag(tagName)
的方法,如果存在,则返回数据库中的现有标记,如果不存在则创建一个新标记employee#tags
(同时,将员工添加到tag#employees
)一件小事,从@Column
映射中移除Employee#tags
。