2017-05-05 46 views
10

Kaynaklardan birinin güncellenebileceği bir dinlenme uygulamasına sahibim.JPA birleştirme kullanırken OptimisticLockException()

  1. updateWithRelatedEntities (String, Store): Aşağıda iki yöntem bu görevi gerçekleştirmek sorumludur kimliği ve PUT istek varlığının deserializing tarafından inşa edilen yeni nesne deposu, sürüm ayarlar aldığı (iyimser kilitleme için kullanılır) Yeni nesnede ve bir işlemde güncellemeleri çağırır.

    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; 
    } 
    
  2. Güncelleme (String, T): bir güncelleme yapmak için genel bir yöntem. Kimliklerin eşleştiğini ve birleştirme işlemini gerçekleştirdiğini kontrol eder. T obj = em.find(type, id); (sürüm şimdi farklı olduğu için) merge tetiklerken biz OptimisticLockException almak anlamına gelir veritabanında depolamak nesnenin bir güncelleştirme yapar:

    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); 
    } 
    

sorun bu çağrı olmasıdır.

Bu neden oluyor? Bunu başarmanın doğru yolu ne olurdu? Bence iyimser kilit sorunu çözmek hangi -

ben tür existingStore için newStore gelen özelliklerini kopyalamak ve birleştirme işlemi için existingStore kullanmak istemiyoruz.

Bu kod bir uygulama sunucusunda çalışmıyor ve JTA kullanmıyorum.

DÜZENLEME: Ben güncellemeyi çağırmadan önce existingStore ayırmak durumunda bu sorunu çözer böylece , T obj = em.find(type, id); mağaza nesnenin bir güncelleme tetiklemez. Soru hala devam ediyor - varlık ayrılmamışken neden tetikliyor?

+0

İyimser kilitleme kavramını anlıyor musunuz? – Kayaman

+0

Evet, kavramı anlıyorum ve neden bu hatayı alıyorum. Anlamadığım şey, JPA'nın, (çağrı) çağrılırken sürümü güncelleştirmesidir. Bu, birleştirme çağrılırken OptimistiLockException'a yönlendirir. –

+0

'get (id)' neye benziyor? – Kayaman

cevap

1

Varlığınızı eklediğiniz koddan göremiyorum ama iyimser kilitleme ile bazı önemli noktaları kaçırdığınızı düşünüyorum ->@Version sürüm alanına açıklama eki. İşletmenizde bu alana sahipseniz, kapsayıcıyı yordamları sorunsuz bir şekilde yapabilmelidir. Lütfen Optimistic Locking'a da dikkat ediniz. İyi bir makale don't break optimistic locking

+0

'@ Sürümü 'alanını kullanıyorum, sorun şu ki, yeni bir nesne ile (seri hale getirme ile oluşturulmuş) güncelleme yapıyorum, bu yüzden' @ Sürümü' alanını manuel olarak ayarlamam gerekiyor. –

+0

Neden sadece nesne deserialize ve 'em.find' yapmak, bu kimliğidir almak ve sonra düzgün varlık güncelleyebilirsiniz yoktur. Ne şu anda yapıyoruz .. Bir çözüm olur – galovics

+0

tür hacky, ama ben kopyalayıp tersi değil istemiyorum hangi alanların biliyorum çünkü ben bunu sevmiyorum. Gelecekte varlık için bir alan eklerseniz Yani, ben de kod temeli başka bir yerine bu alanı eklemek zorunda olduğunu hatırlamak gerekir. –