2011-03-14 35 views
7

Tôi có hai lớp nói Foo và Bar ánh xạ như @OneToOne (hai chiều) sử dụng Hibernate (3.6.1 chính thức) với JPA (2.0) như -Đang cập nhật phiên bản Hibernate bằng tay

@Entity 
public class Foo{ 
    @Id 
    private Long id; 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo") 
    private Bar bar; 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "foo") 
    private Qux qux; 

    @Version 
    private int version; 

    // getters and setters omitted 
} 

@Entity 
public class Bar{ 
    @Id 
    private Long id; 

    @OneToOne 
     @JoinColumn(name = "foo_id", nullable = false) 
    private Foo foo; 

    // getters and setters omitted 
} 

@Entity 
public class Qux { 
    @Id 
    private Long id; 

    @OneToOne 
     @JoinColumn(name = "foo_id", nullable = false) 
    private Foo foo; 

    // getters and setters omitted 
} 

Lưu ý rằng - Bar và Qux không có cột @Version

Nếu chúng tôi cập nhật Bar thì hibernate sẽ không tăng phiên bản của Foo và tương tự cho Qux. Nhưng logic kinh doanh của chúng ta cần - nếu ai đó cập nhật Bar trong Foo và thread khác đang cố gắng cập nhật Qux của cùng Foo nhưng không có Bar cập nhật và ngược lại thì những cập nhật như vậy sẽ thất bại.
Kể từ khi ngủ đông không cập nhật thuộc tính phiên bản của Foo nếu chúng tôi cập nhật Thanh, chúng tôi quyết định cập nhật phiên bản Foo theo cách thủ công (tôi biết nó khá lạ và không được khuyến nghị) nếu chúng tôi cập nhật Thanh và Qux.
Nó hoạt động hoàn hảo tốt .. nhưng tôi lo lắng về một số trường hợp góc trong đồng thời có thể thất bại này hoặc sẽ có hành vi ngoài ý muốn.
Có an toàn để thực hiện loại tinh chỉnh này với phiên bản cho mục đích này không? OR có bất kỳ sự thay thế tốt hơn khác để điều này (tôi đã cố gắng lạc quan/bi quan lực lượng increament)

Trả lời

10

Cách đúng để buộc cập nhật phiên bản như sau:

em.lock(entity, LockModeType.OPTIMISTIC_FORCE_INCREMENT); 

Nó dự định sẽ được sử dụng trong ví dụ các trường hợp.

Các phương pháp khác là EntityManager có thể sử dụng LockModeType.

+0

nhưng để sử dụng, tôi cần một thuộc tính phiên bản trong Bar và Qux, phải không? – Premraj

+0

@Premraj: Có .. – axtavt

+0

Tôi đang cố gắng sử dụng mã này: 'Foo entity = new Foo(); em.persist (foo); int oldVersion = entity.getVersion(); em.lock (thực thể, LockModeType.OPTIMISTIC_FORCE_INCREMENT); return oldVersion == entity.getVersion(); ' Tôi mong đợi điều này là sai, nhưng điều đó là đúng. –

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