2016-07-12 4 views
0

한 부모 개체에서 개체의 Colleciton을 Transfering I 객체의 3 가지 말해봐 - 부모, 자식, 그리고 ChildAttr을최대 절전 모드 - 다른

내 목표는 다른 사용하여 최대 절전 모드로 전환 한 부모에서 자녀의 부분 집합을 전송하는 것입니다 (3.2.5).

객체는 같은 구조로되어 있습니다

public class Parent { 
    Set<Child> children; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "parent") 
    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) 
    public Set<Child> getChildren() { 
    return this.children; 
    } 

    public void setChildren(Set<Child> children) { 
    this.children = children; 
    } 

} 

...

public class Child { 
    Set<ChildAttr> attributes; 
    Parent parent; 

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "child") 
    @Cascade({ org.hibernate.annotations.CascadeType.SAVE_UPDATE, org.hibernate.annotations.CascadeType.DELETE_ORPHAN }) 
    public Set<ChildAttr> getAttributes() { 
    return this.attributes; 
    } 

    public void setAttributes(Set<ChildAttr> attributes) { 
    this.attributes = attributes; 
    } 
} 

...

public class ChildAttr { 
    Child child; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "child_id", nullable = false) 
    public Child getChild() { 
    return this.child; 
    } 

    public void setChild(Child child) { 
    this.child = child; 
    } 
} 

을 지금은 부모의 하위 집합을 취 일부 클라이언트 코드를 실행 말 A의 자식 객체를 부모 B로 이동시키고 이동시킵니다 :

Set<Child> children = getChildrenToTransfer(transferCriteria, parentA); 

parentA.getChildren().removeAll(children); 
manager.saveOrUpdate(parentA); // method also calls flush(); 

parentB.getChildren().addAll(children); 
manager.saveOrUpdate(parentB); // error thrown here. 

parentB를 저장하려고 할 때 오류가 발생합니다.

Found two representations of same collection: com.mycode.Child.attributes; 

현재 애플리케이션은 여러 세션에서 정상적으로 작동하는 것으로 보입니다. - 어떤 사용자가 따라 와서 아이들 세트를 제거한 다음 나중에 얼마간 다른 부모에게 추가합니다. 게다가 부모가 변경 되더라도 실제로 속성 목록을 여러 버전으로 인스턴스화해야하는 이유는 무엇인지 이해하지 못합니다.

앞서 언급 한 오류의 원인은 무엇이며 어떻게 해결할 수 있습니까?

+0

'@ Cascade' 주석을 삭제하려고합니다. 예를 들어 캐스케이드 주석을 삭제 한 후에'@ OneToMany'에 이미 캐스케이드를 전달했습니다. 예를 들어 작업을 시작했습니다.'분리 된 엔티티가 전달 된 상태가됩니다. '가 아니라 정확하게 오류가 있지만 시도 할 수 있습니다 ... – csharpfolk

답변

1

하나의 경험 법칙 : 개체가 개체 그래프로 일관성있게 유지되기 전에 일관성을 유지하는지 확인하십시오. 부모 A에서 모든 자식을 제거하고 부모 B에 추가하고 있지만 부모를 업데이트하지 않았습니다. 그 아이들을위한 링크. 아이에 다음

add(Child child) { 
    child.setParent0(this); 
    children.add(child); 
} 

remove(Child child) { 
    child.setParent0(null); 
    children.remove(child); 
} 

그리고 :

가 부모에 메소드를 추가 :

그래서 나는 다음을 제안 할 것

setParent0(Parent parent) { 
    this.parent = parent; 
} 
setParent(Parent parent) { 
    parent.add(this); 
} 

당신이 어느 방향으로 당신 '에서 추가이 방법 세부 사항을 알고있는 외부 코드없이 일관된 객체 모델을 얻었습니다.

부모에게서 제거하는 것이 더 합리적입니다 ...

따라서이 방법을 시도해보십시오.

+0

이것은 트릭을 수행하고 깨끗한 솔루션입니다. – jiman

1

당신의 양방향 관계 (부모 - 자식) 때문입니다. 다른 부모에게 자식을 제거/추가 할 때는 parent 참조를 업데이트해야합니다.