我有一個休息應用程序,其中一個資源可以更新。下面是兩種方法負責實現這個任務:使用JPA合併時的OptimisticLockException()
updateWithRelatedEntities(字符串,商店):接收ID和被反序列化PUT請求的實體建造新的對象存儲,設置版本(用於樂觀鎖)在新對象上並在事務中調用更新。
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; }
更新(字符串,T):用於使一個更新的通用方法。檢查ID匹配並執行合併操作。
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); }
的問題是,這一呼籲:T obj = em.find(type, id);
觸發在數據庫中存儲對象的更新,這意味着我們觸發merge
時(因爲版本不同,現在)得到OptimisticLockException。
這是怎麼發生的?什麼纔是實現這一目標的正確方法?
我不想複製newStore
的屬性到existingStore
並使用existingStore
進行合併 - 我認爲這會解決樂觀鎖定問題。
此代碼未在應用程序服務器上運行,我沒有使用JTA。
編輯: 如果我調用Update之前分離existingStore,T obj = em.find(type, id);
並不那麼這解決了問題,引發存儲對象的更新。但問題仍然存在 - 爲什麼它在實體不分離時觸發它?
你明白樂觀鎖定的概念嗎? – Kayaman
是的,我理解這個概念以及爲什麼我得到這個錯誤。我不明白的是爲什麼JPA在調用get(id)時更新版本,當調用merge時會導致OptimistiLockException。 –
get(id)是什麼樣的? – Kayaman