2011-04-26 8 views
5

다음과 같은 시나리오를 감안할 때 : 즉JPA 관계가 업데이트 못하고

@Entity 
public class A { 
    @OneToMany(mappedBy = "a", cascade = CascadeType.ALL) 
    private List<B> bList; 
} 

@Entity 
public class B { 
    @ManyToOne() 
    @JoinColumn(name = "a_id", referencedColumnName = "id") 
    private A a; 

    @ManyToOne() 
    @JoinColumn(name = "c_id", referencedColumnName = "id") 
    private C c; 
} 

@Entity 
public class C { 
    @OneToMany(mappedBy="c", cascade=CascadeType.ALL, orphanRemoval=true) 
    @CascadeOnDelete // eclipselink specific optimization annotation 
    private List<B> bList; 
} 

: 객체 A와 객체 C가 모두 B 객체의 수를 포함합니다.

기술적으로 C 개체가 여러 개 포함되어 있고 orphanremoval을 사용하여 개체를 업데이트 할 때, 현재 주석으로 예상대로 작동하는 모든 참조 된 B 개체를 제거하고 싶습니다. 그러나 엔티티 관리자는 캐시에있는 객체 A가 일부 자식을 잃어 버렸음을 이해하지 못하는 것 같습니다. 만약 내가 A 인스턴스를 가지고 있다면 수동으로 bList를 업데이트하거나 새로운 쿼리를 업데이트해야하지만, 새로 가져온 A- 오브젝트조차도 여전히 오래된 것입니다. 반복하십시오 :

  • C 개체가 제거됩니다.
  • 제거는 orphanRemoval을 사용하여 B 오브젝트에 계단식으로 연결됩니다.
  • bList에서 Entity Manager에 캐시 된 개체는이 아닌 입니다.
  • Entity Managers 캐시를 수동으로 제거하면 올바르게 업데이트 된 개체를 검색 할 수 있습니다.

어떻게 해결할 수 있습니까? 엔티티 관리자가 자동으로 지속성 컨텍스트를 업데이트하거나 @JoinColumn에서 캐스케이드 주석을 사용할 수있게 될 것으로 예상되지만, 여기서는 그렇지 않습니다.

EDIT : 개체 C의 bList는 개체 A의 bList가 업데이트되어 변경 사항을 캐스케이드 할 수 없을 때 업데이트되지 않는 것 같습니다. 나는 왜 그런지 모르겠다. 나는 Persistence Context가 아니라 인스턴스화 된 오브젝트에 대해서 이야기하고 있음을 주목하라.

답변

6

JPA는 관계 유지를하지 않으므로 응용 프로그램에서 유지 관리해야합니다. 즉, 엔티티를 삭제할 때 응용 프로그램은 해당 엔티티에 대한 참조를 정리해야합니다. 그것은 외래 키 관계 일 때 분명합니다. 데이터베이스 제약 조건은 대개 완료되지 않은 경우 예외를 발생시키기 때문입니다. 관계에 엄격한 데이터베이스 제약 조건이없는 경우에도 뒤로 참조하는 경우 사용자는 일반적으로 JPA가 캐시를 처리한다고 잘못 생각합니다.

처리 방법은 C 및 B 엔티티에 대한 참조를 제거하는 것입니다. 당신의 객체 모델에서, 그것은 B를 제거하기 위해 A의 bList를 수정하는 것을 의미합니다. 엔티티 제거 이벤트 또는 응용 프로그램 코드를 통해 처리되는 것을 보았습니다. 이 경우 A에는 외래 키가 없으므로 삭제가 발생한 후 (즉, 플러시 또는 커밋 된 후) 영향을받는 A 엔티티를 데이터베이스에서 새로 고칠 수 있습니다.

+0

흠, 관계의 비 소유 측에서 참조를 제거하거나 추가하지 않아도 데이터베이스의 상황이 동일하기 때문에 항상 JPA에서 장면을 처리한다고 가정했습니다. 감사. –

관련 문제