2010-04-27 5 views
1

버전은 onetomany 수집 홀더

@Entity 
public class Expenditure implements Serializable { 
... 
    @OneToMany(mappedBy = "expenditure", cascade = CascadeType.ALL, orphanRemoval = true) 
    @OrderBy() 
    private List<ExpenditurePeriod> periods = new ArrayList<ExpenditurePeriod>(); 

    @Version 
    private Integer version = 0; 
... 
} 

와 자식 하나

@Entity 
public class ExpenditurePeriod implements Serializable { 
... 
    @ManyToOne 
    @JoinColumn(name="expenditure_id", nullable = false) 
    private Expenditure expenditure; 
... 
} 

하나의 트랜잭션 모두 부모와 자식을 업데이트하는 동안은, org.hibernate.StaleObjectStateException가 발생

주어진 지배 기업에 대한 실패 행이 갱신되었다 (또는 저장되지 않은 값 매핑이 올바르지 않음) :

실제로 최대 절전 모드에서는 두 개의 sql 업데이트가 발생합니다. 하나는 부모 속성을 변경하고 또 다른 변화하는 아이 속성. 부모 업데이트 변경 아동을 없애는 방법을 알고 있습니까? 업데이트는 낙관적 인 잠금의 경우 비효율 성과 거짓 긍정의 결과를 가져옵니다. 자식과 부모 모두 상태를 DB에 올바르게 저장합니다. 하나 개의 변화 부모의 속성과 다른 변화 자식 속성 :

최대 절전 모드 버전은

3.5.1-최종

답변

0

(...) 사실, 최대 절전 모드 문제 두 개의 SQL 업데이트입니다. 당신 이 하나의 트랜잭션에 부모와 자식 모두를 업데이트 한 경우

, 이는 예상 된 결과 아닌가요?

부모 업데이트 변경 자녀를 없애는 방법을 알고 있습니까? 업데이트는 낙관적 인 잠금의 경우 비효율 성과 거짓 긍정의 결과를 가져옵니다.

문제점을 이해하지 못하고이를 재현 할 수 없습니다. 다음 테스트 메소드 (트랜잭션 내에서 실행 됨)는 나를 위해 작동합니다 (그리고 부모와 자식을 모두 수정 한 이후 예상대로 두 개의 업데이트를 생성합니다).

@Test 
public void testUpdate() { 
    Expenditure expenditure = new Expenditure(); 
    ExpenditurePeriod expenditurePeriod1 = new ExpenditurePeriod(); 
    ExpenditurePeriod expenditurePeriod2 = new ExpenditurePeriod(); 

    expenditure.getPeriods().add(expenditurePeriod1); 
    expenditure.getPeriods().add(expenditurePeriod2); 
    expenditurePeriod1.setExpenditure(expenditure); 
    expenditurePeriod2.setExpenditure(expenditure); 

    em.persist(expenditure); 
    em.flush(); 

    assertNotNull(expenditure.getId()); 
    assertNotNull(expenditurePeriod1.getId()); 
    assertNotNull(expenditurePeriod2.getId()); 
    assertEquals(Integer.valueOf(0), expenditure.getVersion()); 
    assertEquals(Integer.valueOf(0), expenditurePeriod1.getVersion()); 
    assertEquals(Integer.valueOf(0), expenditurePeriod2.getVersion()); 

    expenditure.setProperty("a"); 
    expenditurePeriod1.setProperty("b"); 

    em.merge(expenditure); 
    em.flush(); 

    assertEquals(Integer.valueOf(1), expenditure.getVersion()); 
    assertEquals(Integer.valueOf(1), expenditurePeriod1.getVersion()); 
    assertEquals(Integer.valueOf(0), expenditurePeriod2.getVersion()); 
} 

귀하의 상황을 대표하지 않는 경우 명확히하십시오.

+0

죄송합니다, 나를위한 _parent_ 업데이트가 2 개 있습니다. 하나는 부모 업데이트이고 다른 하나는 업데이트 자식입니다. 테스트 케이스를 살펴보고 결과를 아래에 입력합니다. –

+0

깨어진 버전 관리를 에뮬레이트하는 테스트를 처음 시도한 것이 아닙니다. 나는 이것이 정말로 Spring 특유의 것이거나 자연적인 특정의 것인가를보기위한 추가적인 시도를 할 것이다. –