【发布时间】:2014-04-08 23:48:42
【问题描述】:
我正在尝试在我的 MySQL 数据库中保存与文章相关的标签。这两列之间的关系是 1:N。每个项目都有一个自动生成的密钥。标签的名称是唯一的。
如果我插入带有现有标签的新文章,我会收到唯一约束的重复条目异常 (MySQLIntegrityConstraintViolationException)。这是我的两个实体:
Article.java
@Entity
public class Article implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@OneToMany(cascade = CascadeType.ALL)
@JoinTable
private Set<Tag> tags = new HashSet<Tag>();
/* getter and setter */
}
标签.java
@Entity
public class Tag implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(unique = true)
private String name;
/* getter and setter */
}
Hibernate 生成以下表格:article、tag、article_tag。第一篇文章的记录是正确的。
我使用以下代码插入新文章(仅用于测试):
Article article = new Article();
Tag tag = new Tag();
/* set the values */
EntityManager em = EMF.getInstance().get();
em.getTransaction().begin();
em.merge(article);
em.getTransaction().commit();
如何让 JPA 使用文章的现有标签而不是创建新标签。如何正确设置这些组件之间的关系?
【问题讨论】:
-
我假设
The name of a tag is unique.表示在包含文章和标签的表格中,标签列被标记为唯一,这实际上意味着如果您尝试插入带有另一个标签的不同文章文章已经有会抛出你的异常。解决方案是将标签存储在一个单独的表中,它们是唯一的,然后通过外键插入对文章表中各种标签的引用。 TL;DR 不要在Articles 中包含Tags,insead 包含可以映射到Tags 的引用 -
没错,我正在这样做。我有第三列
article_tag,其中包含文章的Id和标签。每个文章和标签都存储在自己的表中。 -
尝试将
HashSet对象更改为包含代表TagID 的longs。之后,当您需要检查Article的标签时,您检索存储在Article记录中的long,然后查找Tag表以将标签与您从Article记录中获得的ID 匹配。
标签: java mysql hibernate jpa unique