2011-09-30 5 views
11

orm 구현으로 최대 절전 모드 (3.2.7)에서 jpa를 사용하고 있습니다. 개체를 수정 한 다음 병합했습니다. 또한이 엔티티에 @EntityListeners를 사용하여 일부 특성의 가치를 보장합니다.Jpa - 최대 절전 모드 @Version이 잘못 증가되었습니다.

병합 전에 값을 변경 한 다음 리스너 내부의 @PreUpdate 메소드에서 해당 값을 다시 변경하고 원래 값을 설정하면 엔터티 결과의 버전이 증가하지만 데이터베이스 버전에 이전 값이 있습니다. 이것은 개체가 변경되지 않았기 때문에 발생했다고 생각합니다. db에서는 업데이트되지 않지만 엔티티의 버전은 flush 후에 복원되지 않고 증가됩니다.

@Entity 
@EntityListeners({MyListener.class}) 
public class MyEntity { 

    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private Long id; 

    private String myValue; 

    @Version  
    private Long version ; 
} 

이 리스너 :

public class MyListener { 

    @PreUpdate 
    public void preUpdate(MyEntity ua) { 
     ua.setMyValue("default"); 
    } 
} 
이제

난이 값을 가진 객체 DB에 있다고 가정합니다 ID = 1, myValue = (

더 설명하기 위해, 나는이 객체가 'defalut', 버전 = 1). 이 객체를 읽고 분리하고 클라이언트에 전달한 다음 myValue = 'new'를 사용하여 가져오고 병합 작업을 수행합니다 (리스너가 myValue를 'default'로 변경하고 객체 결과를 db로 수정하지 않음). 플러시하고 트랜잭션을 종료합니다. 커밋 됨). 그 다음에 내 객체에서 version = 2를 찾았지만 db에서 version = 1을 찾았습니다.

최대 절전 모드 버그입니까? 아니면 Jpa 버그?

+0

메서드 호출 계층 구조 및 호출 순서에 대해 언급 할 수 있습니까? 어쩌면 당신의 병합 방법은 업데이트 방법 전에 작동합니다. – mbaydar

+0

최대 절전 모드 더티 검사가 false를 반환하여 개체가 DB (업데이트 쿼리가 생성되지 않음)를 건드리지 않지만 최대 절전 모드가 설정 도구를 처음 호출 할 때 버전 필드를 증가시킬 것으로 추측하고 있습니다. IMHO 버전 필드는 업데이트 된 값이 DB에 기록 될 때마다 증가되어야합니다. 그것은 아마 최대 절전 모드 버그 일 것입니다. –

답변

2

나는 이것이 예상 된 행동이라고 말하고 싶습니다. Hibernate manual에 따르면 @PreUpdate은 "데이터베이스 UPDATE 작업 전에 실행됩니다."입니다. 따라서 Hibernate는 더티 체크를 실행하고 UPDATE가 true를 리턴하도록함으로써 UPDATE를 수행해야한다는 것을 이미 알아 냈습니다.

더티 검사는 @PreUpdate 이후에 일어날 수 없다. 왜냐하면 더티 검사가 참이 아니라면 Hibernate는 @PreUpdate을 호출해서는 안되기 때문이다. 그리고 업데이트가 실행될 경우 버전을 증가시켜야합니다.

@PrePersist에 대한 청취자 사용에 대해 @PreUpdate 대신에 생각해 보셨습니까? 나는 그 과정에서 충분히 일찌감치 일 것이라고 생각한다. 그래서 더러운 사전 검사 일 것이고, 따라서 당신이 원하는 행동을 취할 것이다.

0

스펙 위반 사례입니다. 또는 어쩌면 그 말이 너무 강렬한 표현 일 수도 있습니다. 아마도 이런 구석의 경우가 명확하게 지정되지 않았다고 말할 수 있습니다. JPA 1.0 (최대 절전 모드 3.2.7는 구현 중 하나 인) 사양은 매우 명확 버전이 갱신 될 때에 주문 :

버전 속성은 객체가 데이터베이스에 기록되는 퍼시스턴스 프로 바이더 런타임 으로 업데이트됩니다. 또한 호출 된 엔티티의 기본적인 속성을 설정

은 (JPA 2.0) 소리이다

라이프 사이클 콜백 방법 호출 한 엔티티의 비의 관계 상태를 변경할 수있다.