2012-05-31 2 views
0

현재 프로젝트에서 낙관적 잠금 관리를하고 있습니다. 우리는 JPA 2.0 (hibernate-jpa2.0-api-1.0.1.Final)를 사용하고 데이터 소스는 내가 사용하는 내 실체 "AccordSimple"에서hibernate-jpa2.0을 사용하여 OptimisticLockException을 던지는 방법

를 무슨 짓을 제이보스 7

에 의해 제공됩니다 @Version 주석 :

@Entity 
@Table(name = "AccordSimple") 
public class AccordSimple { 
    @Id 
    @SequenceGenerator(name = "parametresubsidesequence", 
     sequenceName = "parametresubsidesequence", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "parametresubsidesequence") 
    private Long id; 

    // Optimistic lock. 
    @Version 
    private Long version; 

} 

가 그리고 이것은 내 AccordServiceImpl 그와

public AccordDTO updateAccord(AccordDTO accordDTO) throws AppException { 

    AccordSimple accord = getAccordRepository().findByReference(
      accordDTO.getAccordReference()); 

    if (accord == null) { 
     return null; 
    } 

    // copy new values from the DTO... 
    accord.setVariable(accordDTO.getVariable()); 
    // ... 

    // Set the version from the DTO (old version if someone changes before me!) 
    accord.setVersion(accordDTO.getVersion()); 

    getAccordRepository().merge(accord); 
    return accordDTO; 
} 

, 아니 OptimisticLockExceptio 없다 n은 던질 것이다. 병합하기 전에 협정에 포함 된 버전이 내 DB에있는 버전의 경우에도 마찬가지입니다.

나는 그 이유를 발견했다. 이것은 책임 : 나는 내 방식을 변경하는 경우

AccordSimple accord = getAccordRepository().findByReference(
      accordDTO.getAccordReference()); 

이 때문에 :

public AccordDTO updateAccord(AccordDTO accordDTO) throws AppException { 

    AccordSimple accord = new AccordSimple(accordDTO.getAccordReference(), accordDTO.getVersion()); 

    // copy new values from the DTO... 
    accord.setVariable(accordDTO.getVariable()); 
    // ... 

    // Set the version from the DTO (old version if someone changes before me!) 
    accord.setVersion(accordDTO.getVersion()); 

    getAccordRepository().merge(accord); 
    return accordDTO; 
} 

OptimisticLockException을 던졌다됩니다!

버전은 하이버 네이트 캐시에서가 아니라 내 DTO에서 오는 문제. 그래서 엔티티를 분리하면 모든 것이 작동 할 것입니다.하지만 그렇게하고 싶지는 않습니다. (개발자가 잊어 버리면 버그의 출처 ...).

의견이 있으십니까?

답변

1

[편집] 가능한 대안 :

이 거짓 = 삽입과 @PostLoad 또는 추가 열 매핑을 사용하여, 기업에서 별도의 버전 번호를 유지 : 아직, 당신이 시도가있을 수 있음을 시도하지 않은 , 업데이트 가능 = false.

@PreUpdate 메서드를 사용하여 버전 필드와 추가 버전 필드를 확인하십시오. 일치하지 않으면 예외를 throw합니다.

이들 모두를 기본 모델 클래스에 넣을 수 있습니다. 그래서 아무도 엔티티 :


(원래 메시지)

이것은 내가 내 이전 프로젝트에 직면 정확히에서 논리를 넣어 잊지 않을 것입니다. Hibernate는 낙관적 인 잠금 확인을 수행 할 때 엔티티의 버전 필드를 조사하지 않습니다.

내가 그 시간을 해결 한 방법은 DTO를 엔터티에 "병합"할 때 자신을 확인하는 것입니다. 그 당시 DTO와 Entity간에 속성을 매핑하는 유틸리티가 있습니다. 버전 검사는 DTO의 버전 필드에서 추가 엔티티의 문제 일뿐입니다. 해당 엔티티의 속성에 값을 설정하는 대신 일치하지 않을 때 예외가 발생합니다.


+0

는 사실이 ;-) 적용되지 비록 – user1180339

+0

포스트로드와 PreUpdate 주석 귀하의 솔루션은 잘 작동하지만, 그것이 최선의 해결책인지 모르겠어요 당신에게

아마 적용 할 수 없습니다. – user1180339

관련 문제