防止唯一约束的重复条目

时间:2014-03-06 11:16:45

标签: java mysql hibernate jpa unique

我正在尝试保存与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使用文章的现有标签,而不是创建新标签。如何正确设置这些组件之间的关系?

1 个答案:

答案 0 :(得分:1)

通常,文章和标签之间的关系是多对多关系,因为文章可能包含多个标记,并且每个标记都可以在<中重复使用strong>很多文章。

要表明多对多关系, @ManyToMany 注释是必需的。

另外为了明确一点,在OP中它表示 unidirectionaly 一对多关系,因为 @JoinTable 注释具有在很多方面被使用过。这就是创建连接表的原因。另外,如果在Tag类中使用 @ManyToOne 注释,多对一将是另一个单向关系。 请注意,因为它们将作为两个独立的单向关系处理,可能存在奇怪的行为,任何配置都不会影响两个实体,因为它不是一个双重关系。

最后,如果需要具有一对多单向关系但又重用标签,则需要根据其名称检索它们,以便它们具有正确的记录id然后设置为Article实例。如果您尝试设置Tag的新实例,该实例将没有记录ID但已存在的名称,则jpa提供程序将尝试插入新标记,并且将抛出唯一约束异常,因为重复的标签名称。还需要删除tag_id表中article_tag引用的任何唯一约束。