hibernate更新到OneToMany集合时违反java唯一约束
我拥有以下实体:
@Entity
public class License {
// ...
@OneToMany(mappedBy = "license", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true)
private Set<Service> services = new HashSet<>();
// ...
protected void setServices(Set<String> services) {
this.services.clear();
if (services != null) {
this.services.addAll(services.stream().map(s -> new Service(this, s)).collect(toSet()));
}
}
}
@Entity
@Table(uniqueConstraints = @UniqueConstraint(name = "UQ_lic_service", columnNames = { "license_id", "service" }))
public class Service {
// ...
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "license_id", nullable = false)
private License license;
@Column(nullable = false, length = 255)
private String service;
protected Service(License license, String service) {
this.license = license;
this.service = service;
}
}
现在我需要更新License
,如下所示:
License license = getSomeExistingLicenseWithServices(...);
// The existing license has two services "firstService", "secondService"
HashSet<String> services = new HashSet<>();
services.add("firstService");
license.setServices(services);
licenseRepository.save(license); // A spring-data-jpa-repository
运行此操作时,我得到以下异常:
Caused by: org.h2.jdbc.JdbcSQLException: Eindeutiger Index oder Primärschlüssel verletzt: "UQ_LIC_SERVICE_INDEX_8 ON PUBLIC.SERVICE(LICENSE_ID, SERVICE) VALUES (1, 'firstService', 1)"
Unique index or primary key violation: "UQ_LIC_SERVICE_INDEX_8 ON PUBLIC.SERVICE(LICENSE_ID, SERVICE) VALUES (1, 'firstService', 1)"; SQL statement:
insert into service (id, lock_no, license_id, service) values (null, ?, ?, ?) [23505-196]
当我用一个新的HashSet
调用setServices
时,我希望所有的“旧的”(=“孤立的”)Service
都被删除。我做错了什么?蒂亚
# 1 楼答案
在设置服务之前,请尝试清除列表:
然后
更新
为了实现这一点,重要的是实现
equals
和hashCode
方法。我正在使用ApacheCommonsLang库# 2 楼答案
只是打电话。集合上的clear()可能不够。在清除集合的每个组件之前,可能需要显式调用remove()
请在清除集合之前尝试添加类似的内容,以查看这是否解决了问题