2017-09-22 7 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] 

나는 모두 'old'(= '고아')라고 예상했습니다. ServicesetServicesHashSet으로 전화하면 삭제 될 것입니다. 내가 뭘 잘못하고 있니? 티아!

답변

2

시도 목록 명확 전에 설정 서비스 :

license.getServices().clear(); 

그리고

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

이 일을하려면 UPDATE, 그것은 중요하다구현3210 및 hashCode 방법. 아파치 공유 라이브러리를 사용하고 있습니다.

@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-value –

+0

좋습니다. 나는 그것을 시도했지만 같은 오류가 발생합니다. – t777

4

집합에서 .clear()를 호출하는 것만으로는 충분하지 않을 수 있습니다. 집합을 지우기 전에 집합의 각 구성 요소에 대해 remove()를 명시 적으로 호출해야합니다.

그 문제를

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

감사합니다. 그러나 나는 이것을 할 수 없다. 계단식 솔루션이 필요합니다. – t777