2011-09-30 36 views
11

Tôi đang sử dụng jpa với hibernate (3.2.7) như triển khai thực hiện. Tôi có một thực thể đang được sửa đổi và sau đó sáp nhập. Tôi cũng có một @EntityListeners trên thực thể này để đảm bảo một số thuộc tính đang được đánh giá.Jpa - Hibernate @Version tăng không chính xác

Nếu tôi thay đổi giá trị trước khi hợp nhất, sau đó thay đổi giá trị đó trong phương thức @PreUpdate bên trong Trình nghe, đặt giá trị gốc, phiên bản của tôi trên kết quả thực thể tăng lên, nhưng trên phiên bản cơ sở dữ liệu có giá trị trước đó. Tôi nghĩ rằng điều này là do đối tượng không thay đổi, do đó, trên db nó không được cập nhật, nhưng phiên bản trên thực thể được alredy tăng lên mà không được phục hồi sau khi tuôn ra.

Để giải thích rõ hơn, tôi có đối tượng này:

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

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

    private String myValue; 

    @Version  
    private Long version ; 
} 

và Listener này:

public class MyListener { 

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

Bây giờ giả sử tôi có trên db một đối tượng với các giá trị: (id = 1, myValue = 'defalut', phiên bản = 1). Tôi đọc đối tượng này, tách ra, chuyển nó cho client và lấy nó trở lại với myValue = 'new' và thực hiện thao tác trộn (listener thay đổi myValue thành 'default' và kết quả đối tượng chưa được sửa đổi thành db), flush và exit from transaction (được cam kết). Sau đó tôi tìm thấy phiên bản = 2 trên đối tượng của tôi, nhưng phiên bản = 1 trên db.

Đó có phải là lỗi hibernate không? Hoặc một lỗi Jpa?

+0

Bạn có thể đề cập đến thứ bậc cuộc gọi phương thức và chuỗi cuộc gọi không. Có thể phương thức hợp nhất của bạn hoạt động trước phương thức cập nhật. – mbaydar

+0

Tôi đoán rằng kiểm tra bẩn hibernate trả về false vì vậy đối tượng của bạn không chạm vào DB (không có truy vấn cập nhật được tạo ra), nhưng hibernate có thể tăng trường phiên bản của bạn lần đầu tiên bạn gọi một setter. IMHO trường phiên bản chỉ nên được tăng lên bất cứ khi nào giá trị cập nhật được ghi trong DB. Nó có thể là một lỗi ngủ đông. –

Trả lời

2

Tôi có thể nói đây là hành vi mong đợi. Theo số Hibernate manual, @PreUpdate là "Đã thực thi trước thao tác UPDATE cơ sở dữ liệu.". Vì vậy, Hibernate đã tìm ra nó đã làm UPDATE bằng cách chạy kiểm tra bẩn, và có nó trở lại đúng sự thật.

Kiểm tra bẩn không thể xảy ra SAU @PreUpdate, vì Hibernate không nên gọi số @PreUpdate trừ khi kiểm tra bẩn là đúng. Và nếu một bản cập nhật sẽ được chạy, phiên bản sẽ được tăng lên.

Bạn đã nghĩ đến việc sử dụng trình nghe cho @PrePersist, thay vì @PreUpdate? Tôi tin rằng đó là đủ sớm trong quá trình đó nó sẽ được kiểm tra trước bẩn, và do đó có hành vi mà bạn muốn.

0

Đối với tôi, có vẻ như vi phạm đặc điểm kỹ thuật. Hoặc có lẽ đó là từ ngữ quá mạnh, tốt hơn có thể nói rằng một trường hợp góc như vậy là không rõ ràng đủ quy định. JPA 1.0 (Hibernate 3.2.7 là một trong những triển khai) đặc điểm kỹ thuật phép thuật khá rõ ràng khi phiên bản nên được cập nhật:

Thuộc tính phiên bản được cập nhật bởi thời gian chạy cung cấp bền vững khi đối tượng được ghi vào cơ sở dữ liệu.

Ngoài ra thiết lập thuộc tính cơ bản trong thực thể gọi là to (JPA 2.0): phương thức callback

Một vòng đời có thể thay đổi tình trạng không mối quan hệ của thực thể mà trên đó nó được gọi.

Các vấn đề liên quan