我试图保存与我的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 */
}
Tag.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 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使用现有标签的文章,而不是创建一个新的。如何正确设置这些组件之间的关系?
我假设'标签的名称是唯一的.'意味着在包含文章和标签的表中,标签列被标记为唯一,这实际上意味着如果您尝试插入带有标签的其他文章另一篇文章已经有了会抛出你的异常。解决这个问题的方法是将标签存储在独立的表中,并且只通过外键插入对文章表中不同标签的引用。 ** TL; DR ** *不在'文章'中包含'标签',insead包含可以映射到'标签*的引用* –
正是我正在这样做。我有第三列'article_tag',它包含文章和标签的'Id'。每篇文章和标签都存储在自己的表格中。 – hofmeister
尝试将“HashSet”对象改为包含代表“标记”ID的“long”。之后,当您需要检查“Article”的标签时,您可以检索存储在“Article”记录中的“long”,然后查找“标签”表以将标签与从“Article”记录中获取的ID相匹配。 –