2009-08-06 8 views
1

내 상황은 다음과 같다 : 양방향 부모 자식 관계를 포함하는 객체를 데이터베이스에로드한다. 나중에 해당 객체가 내 UI에로드되어 자식 세트에서 자식 수를 삭제하는 등 변경 작업을 수행 할 수 있습니다. 그런 다음 객체의 수정 된 사본이 saveOrUpdate 메소드를 사용하여로드됩니다. 그러나이 수정 된 사본이 저장되면 삭제 된 하위 항목이 데이터베이스에 남아있게됩니다 (새로운 하위 항목이 집합에 잘 추가됨). 이 프로세스에서 오류가 발생하지는 않지만 데이터베이스에서 실제로 제거하려면 이러한 제거 된 자식이 필요합니다. 내 절전 모드와 자바 코드의 관련 부분을 아래에 붙여 넣었다. 최대 절전 모드 설정Hibernate는 데이터베이스에서 자식을 제거 할 수 없다.

<bag name="specimenTypes" table="masterPkSpecimenType" cascade="all-delete-orphan" inverse="true"> 
    <key column="runid"/> 
    <one-to-many class="SpecimenType"/> 
</bag> 

아이 :

<many-to-one name="reportCriteriaBean" class="ReportCriteriaBean" column="runid" not-null="true" /> 

부모 오브젝트 코드 :

public List<SpecimenType> getSpecimenTypes() { 
    return specimenTypes; 
} 

public void setSpecimenTypes(List<SpecimenType> specimenTypes) { 
    this.specimenTypes = specimenTypes; 
    if(this.specimenTypes != null){ 
     for(SpecimenType specType : this.specimenTypes){ 
      specType.setReportCriteriaBean(this); 
     } 
    } 
} 

하위 오브젝트 코드 :

public ReportCriteriaBean getReportCriteriaBean() { 
    return reportCriteriaBean; 
} 
public void setReportCriteriaBean(ReportCriteriaBean reportCriteriaBean) { 
    this.reportCriteriaBean = reportCriteriaBean; 
} 

부모 설정을 최대 절전 모드

편집 :

은 분명히 내 문제 때문입니다 명시 적으로 제가 DB에서 부모 개체를 검색 한 후() setSpecimenTypes를 호출, 그리고 업데이트 된 객체를 저장하기 전에 다시합니다. 내가 이것을하는 이유는 일부 동적 목록 바인딩 때문에 List에 특정 구현 (특히 Apache의 LazyList)이 필요하기 때문입니다. UI에 표시 될 때입니다. 그러나 개체가 DB에서 가져 오면이 방법으로 구현되지 않으므로 데이터베이스에서 가져온 일반 List의 LazyList 복사본을 만들고 setSpecimenTypes()를 호출하여 새로 채워진 LazyList로 바꿉니다. 누구든지이 일을 할 수있는 방법을 알고 있습니까?

답변

0

지도가 올바르게 표시됩니다. 어떻게 아이들을 없애고 있니? getSpecimenTypes().remove(X)과 비슷한가요? 아니면 특별한 방법이 있습니까? 그렇다면 그것을 게시 할 수 있습니까?

또한 부모 개체가 UI 레이어로 전송 된 후 다시 동일한 세션 내에서 완료 될 때? 중간에 setSpecimenTypes()으로 전화하여 어린이 컬렉션을 재설정하지 않으셨습니까? (정화 기준)

업데이트 :

specimenTypes 재설정은 확실히 문제입니다. Hibernate는 당신이 특정 엘리먼트를 제거했다는 것을 어떻게 알 수 있을까? Hibernate 자신의 PersistentList 내에서 삭제가 추적되어 부모 객체가로드 될 때 목록을 래핑합니다.

LazyList (저는 Commons Collections의 컬렉션을 의미한다고 가정합니다)는 데코레이터이므로 부모 객체 내에서 specimenTypes 컬렉션을 LazyList로 감싸는 다른 getter 메소드를 생성하여 반환 할 수 있습니다 (멤버에서 캐싱). 반복 액세스 시도 중 효율성을위한 변수).

결론은 Hibernate에서 관리하는 컬렉션을 자신의 버전으로 덮어 쓰지 않아야한다는 것입니다.

+0

개체를 업데이트하기 전에 setSpecimenTypes()를 호출하고 있습니다. 이유는 (내 게시물에 대한 업데이트에서 설명한대로)이 문제가 왜 중요하지는 않습니다. 현재 자식 집합에 포함 된 내용을 반영하도록 자식 목록을 업데이트하면 안 됩니 다. 이로 인해 오래된 자식 DB 항목이 제거됩니까? – TimmyJ

+0

도움을 주셔서 감사합니다. 나는 아직도 문제가있다.getter를 변경하여 데코 레이팅 된 List를 반환 할 때 부모 클래스가 DB에서 꺼내 질 때 다음 오류가 발생합니다. cascade = "all-delete-orphan"인 컬렉션은 소유하는 엔터티 인스턴스에서 더 이상 참조하지 않았습니다. 나는 setSpecimenTypes가 결코 호출되지 않을 것이라고 확신한다 (나는 프라이빗으로 만들었다). 위에서 언급했듯이 다른 getter를 만들어야하는데, 현재와 같은 getter를 대체하지 않아야합니다. 내 방식이 올바르지 않은 이유가 있을까요? – TimmyJ

+0

기존 getter에서 데코 레이팅 된 목록을 반환하는 문제는 더 이상 Hibernate의 PersistentList가 아니라는 것입니다. Hibernate는 당신이 랩핑했다는 것을 알지 못한다. (또는 언 래핑하는 방법) - 거기에 있던 PersistentList가 이제 사라진 것을 볼 수있다. 따라서 예외적이다. 당신은 정말로 다른 getter가 필요하다. - 그러나 코드가'getSpecimenTypes()'에 의존한다면, 당신은 private getSpecimentTypesDB()를 만들고 그것을 Hibernate에 매핑 할 수있다. 필자는 개인적으로 비즈니스 객체가 아닌 UI 빈을 꾸미는 것을 선호하지만, 두 접근법 중 하나가 그 자리를 차지합니다. – ChssPly76

관련 문제