2014-12-08 14 views
9

Tôi đang sử dụng Spring with Hibernate. Tôi đang chạy thử nghiệm JUnit như thế này:OptimisticLockException trong khóa bi quan

String number = invoiceNumberService.nextInvoiceNumber(); 

và invoiceNumberService phương pháp là:

InvoiceNumber invoiceNumber = invoiceNumberRepository.findOne(1L); 

nó được sử dụng phương pháp kho dữ liệu mùa xuân đơn giản, và nó hoạt động tốt. Nhưng khi tôi ghi đè phương pháp này để sử dụng khóa:

@Lock(LockModeType.PESSIMISTIC_READ) 
@Override 
InvoiceNumber findOne(Long id); 

Tôi nhận được "javax.persistence.OptimisticLockException: Row đã được cập nhật hoặc bị xóa bởi một giao dịch"

Tôi không thể hiểu tại sao khóa ngoại lệ lạc quan của nó , trong khi tôi đang sử dụng khóa bi quan? Và đâu là phần này khi một giao dịch khác đang thay đổi thực thể này? Tôi đã đào rất nhiều câu hỏi tương tự và tôi khá tuyệt vọng về điều này. Nhờ sự giúp đỡ

Giải pháp:
Vấn đề là trong hàm init của tôi trong lớp thử nghiệm:

@Before 
public void init() { 
    InvoiceNumber invoiceNumber = new InvoiceNumber(1); 
    em.persist(invoiceNumber); 
    em.flush(); 
} 

Có thiếu

em.flush(); 

nào tiết kiệm dữ liệu vào cơ sở dữ liệu , do đó findOne() hiện có thể truy xuất nó

+0

Tôi đã gặp sự cố tương tự và cùng một giải pháp. Âm thanh như một lỗi với tôi rằng Hibernate không tuôn ra bởi chính nó. – gnomie

Trả lời

0

Ques tion: Bạn đã đưa chú thích @transcational vào dao hoặc lớp dịch vụ chưa? nó xảy ra do lý do hai giao dịch đồng thời cố gắng thay đổi dữ liệu của cùng một bảng .. Do đó, nếu bạn loại bỏ tất cả chú thích khỏi lớp dao và đặt trong lớp dịch vụ, nó sẽ giải quyết vấn đề này ... bởi vì tôi đối mặt với loại vấn đề tương tự. Hy vọng điều đó sẽ hữu ích.

+0

Bạn đã đọc câu hỏi từ trên xuống dưới chưa? OP đưa nhầm câu trả lời vào câu hỏi thay vì trả lời. – BalusC

0

Chỉ vì lợi ích của nó, tôi sẽ đăng bài sau đây, nếu có ai không đồng ý, hãy sửa tôi. Nói chung trong java, bạn nên sử dụng Spring/hibernate và JPA. Hibernate thực hiện JPA, do đó bạn sẽ cần các phụ thuộc cho Spring và Hibernate.

Tiếp theo để Spring/hibernate quản lý các giao dịch của bạn và phần cam kết. Thực hành không tốt để tuôn ra/tự mình thực hiện dữ liệu của bạn.

Ví dụ chúng ta hãy giả định phương pháp sau:

public void changeName(long id, String newName) { 
    CustomEntity entity = dao.find(id); 
    entity.setName(newName); 
} 

Không có gì sẽ xảy ra sau khi phương pháp này (bạn có thể gọi hợp nhất và cam kết). Nhưng nếu bạn chú thích nó với @Transactional, thực thể của bạn sẽ được quản lý và vào cuối phương thức @Transactional Spring/hibernate sẽ cam kết các thay đổi của bạn. Vì vậy, điều này là đủ:

@Transactional 
public void changeName(long id, String newName) { 
    CustomEntity entity = dao.find(id); 
    entity.setName(newName); 
} 

Không cần phải gọi xả, Spring/Hibernate sẽ xử lý tất cả các mớ hỗn độn cho bạn. Đừng quên rằng các bài kiểm tra của bạn phải gọi các phương thức @Transactional, hoặc phải là @Transactional.

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