2017-09-22 83 views
0

我有以下實體:唯一約束違反有關休眠更新到一對多集合

@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] 

我預計所有'老'(='孤立')Service s將被刪除,當我撥打setServices與新的HashSet。我做錯了什麼? TIA!

回答

2

嘗試明確列表以前設置服務:

license.getServices().clear(); 

然後

license.getServices.add("firstService"); 
licenseRepository.save(license); 

UPDATE

爲了使這項工作,這是很重要實施equalshashCode方法。我正在使用apache commons lang庫

@Override 
public int hashCode() { 
    return new HashCodeBuilder().append(idService).toHashCode(); 
} 

@Override 
public boolean equals(Object obj) { 
    if (!(obj instanceof Service)) 
     return false; 

    Service other = (Service) obj; 

    return new EqualsBuilder() 
      .append(this.idService, other.idService) 
      .isEquals(); 
} 
+0

前加入這樣的事情,我已經這樣做,在'License.setServices'。 – t777

+0

是不一樣清除之前單獨添加 查找此http://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#collections-值 –

+0

好吧。我試過了,但是我得到了同樣的錯誤。 – t777

4

只要在集合上調用.clear()可能不夠。可能它需要明確調用remove(),然後清除它的每個組件。

請嘗試清除設置,看看是否能解決問題

this.services.forEach(service -> {licenseRepository.remove(service)}); 
+0

謝謝。但我不能這樣做。我需要一些級聯解決方案。 – t777

相關問題