2014-04-23 7 views
0

브랜드 (동물 용)와 브랜드가 적용될 수있는 동물 Species가 연관되어 있습니다. 여기에는 Brand 모델, Species 모델 및 Relational Model BrandSpecies가 있습니다. 제 질문과 관련된 두 가지는 브랜드 모델과 BrandSpecies 모델입니다.Hibernate @OneToMany association은 부모 엔티티를 저장할 때 중복을 생성합니다.

양식은 이미 브랜드와 관련된 수종의 ID를 전송합니다. 나는 세트를 통해 반복하고 종들이 이미 설명되었는지 확인하는 것을 피하기를 바라고 있습니다.

종 집합에서 clear()를 호출하고 서버에서 보낸 모든 ID를 추가하려고 시도했지만 개체가 지속되면 이전 DB 레코드가 남아 있습니다.

내 브랜드 협회 :

은 브랜드 종 협회

public class PendingBrandModel implements Serializable, Comparable<PendingBrandModel> { 
    . 
    . 
    . 
@JsonBackReference 
@OneToMany(mappedBy="pending_brand", cascade = {CascadeType.ALL}) 
private Set<PendingBrandSpeciesModel> selected_species; 

    ... 
} 
:

public class PendingBrandSpeciesModel implements Serializable { 
... 
@JsonManagedReference 
@ManyToOne() 
@JoinColumn(name="pending_brand", referencedColumnName="id", nullable = false) 
private PendingBrandModel pending_brand; 

@JsonManagedReference 
@ManyToOne() 
@JoinColumn(name="species", referencedColumnName="id", nullable = false) 
private BrandSpeciesModel species; 
// below here are the hashCode and equals override methods... 
@Override 
public int hashCode() { 
    final int prime = 31; 
    int result = 1; 
    result = prime * result + ((id == null) ? 0 : id.hashCode()); 
    return result; 
} 

/* (non-Javadoc) 
* @see java.lang.Object#equals(java.lang.Object) 
*/ 
@Override 
public boolean equals(Object obj) { 
    if (this == obj) 
     return true; 
    if (obj == null) 
     return false; 
    if (getClass() != obj.getClass()) 
     return false; 
    PendingBrandSpeciesModel other = (PendingBrandSpeciesModel) obj; 
    Boolean brandIDsMatch = false; 
    Boolean speciesIDsMatch = false; 
    if(pending_brand != null && other.getPending_brand() != null) { 
     if((pending_brand.getId() != null && other.getPending_brand().getId() != null) && 
       pending_brand.getId().intValue() == other.getPending_brand().getId().intValue()) 
      brandIDsMatch = true; 
    } 
    if(species != null && other.getSpecies() != null) { 
     if((species.getId() != null && other.getSpecies().getId() != null) && 
       species.getId().intValue() == other.getSpecies().getId().intValue()) 
      speciesIDsMatch = true; 
    } 
    if(brandIDsMatch && speciesIDsMatch) 
     return true; 
    else 
     return false; 
} 
} 

관련 종의 컬렉션을 채우는 나의 방법 :

public void assignBrandSpecies(PendingBrandModel brandObj) { 
     if(checkedSpeciesTypesStr != null) { 
      String[] speciesList = checkedSpeciesTypesStr.split(ADDL_SEPARATOR); 
      // Clear existing species 
      if(brandObj.getSelected_species() != null) 
       brandObj.getSelected_species().clear(); 
      // Add the roles the admin has chosen 
      for(String speciesID : speciesList) { 
       PendingBrandSpeciesModel newSpecies = new PendingBrandSpeciesModel(); 
       newSpecies.setPending_brand(brandObj); 
       newSpecies.getSpecies().setId(Integer.parseInt(speciesID)); 
       if(brandObj.getSelected_species() == null) 
        brandObj.setSelected_species(new HashSet<PendingBrandSpeciesModel>()); 
       brandObj.getSelected_species().add(newSpecies); 
      } 
     } 
    } 

나는 그것을 시도했습니다 .clear() 코드와 함께 사용하지만 동작은 동일하게 유지됩니다. 그리고 나서 다 실행 된 후에 브랜드 객체를 업데이트합니다.

pendingBrandDAO.update(brandObj); 

그러나, 어떤 기존 기록은 DB에 남아 새로운 관계없이 이미 사용 된 상표와 종 ID의 조합을 추가 해요 경우의 추가됩니다.

+0

PendingBrandModel의 컬렉션에서 PendingBrandSpeciesModel을 검색하고 해당 개체를 업데이트 해 볼 수 있습니다. –

답변

0

게시 된 코드가 불완전하지만 (... 's), 내 질문에 hashCode/equals와 관련이 있으며 컬렉션에 처음 추가 될 때 ID가 null 일 수 있다는 점이 문제가됩니다. 계산 된 hashCode/equals 값이 컬렉션에 처음 삽입 된 시점에서 변경되면 이후 컬렉션에서 "발견"되지 않습니다. 이것은 게시 한 코드를 기반으로 한 대략적인 추측입니다. 어쩌면 전체 코드가 더 명확하게 설명 할 수 있습니다.

이 오래된 기사 (아래 링크 참조)는 최대 절전 모드 커뮤니티에서 "논란의 여지가있는"것으로 여겨지지만 어떤 경우에는 제안 된 해결책이 일부 최대 절전 모드 다이버들에 의해 항상 수용되는 것은 아니지만 가능한 함정을 설명합니다. :

Don't let hibernate steal your identity

1

나는) 비슷한 문제를 재 작성 해시 코드()와 같음을 (해결했다.