Hazırda bekletme özelliğini kullanarak varlığın sürümünü değiştirmeden veritabanındaki varlığı güncelleyebilir miyim?Belirli bir güncelleştirme için hazırda bekleyen sürüm artışını kapatmak mümkün mü?
Web uygulamamı kullanarak kullanıcılar varlıklar oluşturabilir veya güncelleyebilir. Ve herhangi bir kullanıcı operasyonundan sonra bu varlıkları “işleyen” bir başka asenkron süreçtir. Kullanıcı, varlık “işlendikten” önce güncelleme için bir varlık açarsa, ancak “işlendikten” sonra kaydetmeye çalışırsa, kullanıcı “OptimisticLockException” alır ve girilen tüm veriler kaybolur. Ancak, kullanıcı tarafından sağlanan verilerle senkronize olmayan süreçte güncellenen verilerin üzerine yazmak istiyorum.
//user creates entity by filling form in web application
Entity entity = new Entity();
entity.setValue("some value");
entity.setProcessed (false);
em.persist(entity);
em.flush();
em.clear();
//but after short period of time user changes his mind and again opens entity for update
entity = em.find(Entity.class, entity.getId());
em.clear(); //em.clear just for test purposes
//another application asynchronously updates entities
List entities = em.createQuery(
"select e from Entity e where e.processed = false")
.getResultList();
for (Object o: entities){
Entity entityDb = (Entity)o;
someTimeConsumingProcessingOfEntityFields(entityDb); //update lots of diferent entity fields
entityDb.setProcessed(true);
em.persist(entityDb);
}
em.flush(); //version of all processed entities are incremented.
//Is it possible to prevent version increment?
em.clear();
//user modifies entity in web application and again press "save" button
em.merge(entity); //em.merge just for test purposes
entity.setValue("some other value");
entity.setProcessed (false);
em.persist(entityDb);
em.flush(); //OptimisticLockException will occur.
//Is it possible to prevent this exception from happening?
//I would like to overwrite data updated in asynchronous process
//with user provided data.
Ve varlık: Ben böyle bir davranış (JPA + hazırda) neden ihtiyaç
program parçası, mikroişlemciyi göstermek için
gerçeklik ben benzer bir sorunu olan çok daha sınıfları var ise@Entity
@Table(name = "enities")
public class Entity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Version
private int versionNum;
@Column
private String value
@Column
private boolean processed;
//… and so on (lots other properties)
}
- ben Bazı zarif olmayan müdahaleci çözüm arıyorum.
Bana öyle geliyor ki bu oldukça olağan bir senaryo. Ancak, böyle bir işlevin nasıl elde edileceğine dair herhangi bir bilgi bulamadım.
Bu çözüm, iyimser kilit denetimini tamamen kapatacak ve birden çok kullanıcı web arayüzünü kullanarak aynı varlığı düzenleyecektir, ancak bunun olmasını istemiyorum. Sorun, kullanıcı öğeyi güncelleştirmez, ancak daha sonra eşzamansız süreç öğeyi günceller. Bu nedenle, bir zaman uyumsuz süreçteki varlık güncellemesini değiştirmem gerektiğini düşünüyorum. – Palladium
Ayrıca, varlığını sürüm özniteliği olmadan farklı bir sınıfa eşleyebilir ve yalnızca async çağrınızda kullanabilirsiniz. – Brian
Evet, bu işe yarayacaktı, ancak maalesef bu çok fazla ilave refactoring gerektiriyordu (alan sınıflarımı tamamen yeniden tasarla). Uygulamamda tüm alan sınıfları (100'den fazla sınıf), alan versionNum ile süper sınıfı genişletir ve bunların önemli bir kısmı bazı asenkron işlemlerle güncellenir. Bu nedenle, belirli bir nedenle alanın değiştirilmesi çok “müdahaleci” bir çözüm olacaktır. Bu durumda, bazı durumlarda (ancak "dallanma" hazırda bekletme anlamına gelir) terfi artışına çevirmek için hazırda varsayılan DefaultFlushEntityEventListener sınıfının üzerine yazmanın daha kolay olacağını düşünüyorum. – Palladium