多对多关系 JPA - 唯一约束

时间:2021-06-30 02:28:57

标签: java mysql hibernate jpa many-to-many

我有 2 个实体,Event 和 Tag,处于多对多关系中。标签应该有唯一的名称,所以我对其进行了限制。

对于唯一的标签名称,它的工作原理与预期一样,我保存了一批新事件,并且条目会自动插入到标签和连接表中。

但是当我尝试保存具有重复名称标签的事件时,由于违反约束而引发错误。

有没有一种无需手动检查和插入所有事件/标签的方法?

代码如下:

事件实体:

@Entity
@Table(name = "event")
class Event {

    @Id long id;
    
    @ManyToMany(cascade = { CascadeType.ALL })
    @JoinTable(name = "event_tag",
            joinColumns = @JoinColumn(name = "event_id"),
            inverseJoinColumns = @JoinColumn(name = "tag_id"))
    private Set<Tag> tags;

    // other properties
}

标签实体:

@Entity
@Table(name = "tag", uniqueConstraints = @UniqueConstraint(columnNames = "name"))
public class Tag {

    @Id long id;

    @Column(name = "name", unique = true)
    private String name;
    
    @ManyToMany(mappedBy = "tags", cascade = { CascadeType.ALL })
    private Set<Event> events;
}

我正在使用 JpaRepository 的方法 saveAll 来持久化事件。它抛出:

java.sql.SQLException: Duplicate entry 'xxxxx' for key 'uq_tag_name'
at org.mariadb.jdbc.internal.protocol.AbstractQueryProtocol.readErrorPacket(AbstractQueryProtocol.java:1694) ~[mariadb-java-client-2.7.3.jar:na]

我看到了一些类似的问题,但还没有找到一个可行的答案。

1 个答案:

答案 0 :(得分:0)

这是因为 { CascadeType.ALL } 当您设置 CascadeType.ALL 时,休眠会更改 Tag 表,如果需要,请为 Tag 插入数据。您应该删除 CascadeType.ALL,如果您得到(无法插入瞬态对象),则应使用flush 来处理