Tôi có một ứng dụng còn lại, nơi một trong các tài nguyên có thể được cập nhật. Dưới đây là hai phương pháp có trách nhiệm để đạt được nhiệm vụ này:OptimisticLockException khi sử dụng JPA merge()
updateWithRelatedEntities (String, Store): nhận được id và cửa hàng đối tượng mới được xây dựng bởi deserializing yêu cầu PUT tổ chức nào, đặt phiên bản (sử dụng cho khóa lạc quan) về cập nhật đối tượng và cuộc gọi mới trong giao dịch.
public Store updateWithRelatedEntities(String id, Store newStore) { Store existingStore = this.get(id); newStore.setVersion(existingStore.getVersion()); em.getTransaction().begin(); newStore = super.update(id, newStore); em.getTransaction().commit(); return newStore; }
cập nhật (String, T): một phương pháp chung để làm một bản cập nhật. Kiểm tra xem id có khớp và thực hiện thao tác hợp nhất hay không.
public T update(String id, T newObj) { if (newObj == null) { throw new EmptyPayloadException(type.getSimpleName()); } Type superclass = getClass().getGenericSuperclass(); if (superclass instanceof Class) { superclass = ((Class) superclass).getGenericSuperclass(); } Class<T> type = (Class<T>) (((ParameterizedType) superclass).getActualTypeArguments()[0]); T obj = em.find(type, id); if (!newObj.getId().equals(obj.getId())) { throw new IdMismatchException(id, newObj.getId()); } return em.merge(newObj); }
Vấn đề là cuộc gọi này: T obj = em.find(type, id);
gây nên một bản cập nhật của cửa hàng đối tượng trong cơ sở dữ liệu có nghĩa là chúng tôi nhận OptimisticLockException khi kích hoạt merge
(vì các phiên bản hiện nay khác nhau).
Tại sao điều này lại xảy ra? Điều gì sẽ là cách chính xác để đạt được điều này?
Tôi không muốn sao chép các thuộc tính từ newStore
đến existingStore
và sử dụng existingStore
để hợp nhất - theo tôi nghĩ, giải quyết vấn đề khóa lạc quan.
Mã này không chạy trên máy chủ ứng dụng và tôi không sử dụng JTA.
EDIT: Nếu tôi tách CurrentStore trước khi gọi cập nhật, T obj = em.find(type, id);
không kích hoạt cập nhật đối tượng cửa hàng để giải quyết vấn đề. Câu hỏi vẫn còn mặc dù - tại sao nó kích hoạt nó khi thực thể không tách rời?
Bạn có hiểu khái niệm về khóa lạc quan không? – Kayaman
Có, tôi hiểu khái niệm và lý do tại sao tôi nhận được lỗi này. Những gì tôi không hiểu là lý do tại sao JPA cập nhật phiên bản khi gọi get (id) mà sau đó dẫn vào OptimistiLockException khi gọi hợp nhất. –
Hình thức 'get (id)' trông như thế nào? – Kayaman