Có thể cập nhật thực thể trong cơ sở dữ liệu mà không sửa đổi phiên bản của thực thể bằng hibernate không?Có thể tắt tăng phiên bản ngủ đông cho bản cập nhật cụ thể không?
Sử dụng ứng dụng web của tôi mà người dùng có thể tạo hoặc cập nhật đối tượng. Và đâu là một quá trình không đồng bộ khác mà "xử lý" các thực thể này sau bất kỳ thao tác người dùng nào. Nếu người dùng mở thực thể để cập nhật trước khi thực thể được "xử lý", nhưng cố gắng lưu nó sau khi nó được "xử lý", người dùng sẽ nhận được "OptimisticLockException" và tất cả dữ liệu đã nhập của anh ta sẽ bị mất. Nhưng tôi muốn ghi đè lên dữ liệu được cập nhật trong quá trình không đồng bộ với dữ liệu do người dùng cung cấp.
đang snipet để chứng minh lý do tại sao tôi cần phải hành vi như vậy (JPA + Hibernate):
//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.
Và thực thể của tôi:
@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)
}
Trên thực tế tôi đã học nhiều hơn với vấn đề tương tự - vì vậy tôi đang tìm kiếm một số giải pháp thanh lịch không xâm phạm.
Dường như với tôi đây là kịch bản khá bình thường. Nhưng tôi không thể tìm thấy bất kỳ thông tin nào để đạt được chức năng như vậy.
Giải pháp này sẽ tắt hoàn toàn kiểm tra khóa lạc quan sau đó nhiều người dùng chỉnh sửa cùng một thực thể bằng giao diện web, nhưng tôi không muốn điều đó xảy ra. Vấn đề không phải là sau đó người dùng cập nhật thực thể, nhưng sau đó quá trình không đồng bộ cập nhật thực thể. Vì vậy, tôi nghĩ rằng tôi cần bằng cách nào đó sửa đổi cập nhật của thực thể trong quá trình không đồng bộ. – Palladium
Bạn cũng có thể ánh xạ thực thể đến một lớp khác mà không có thuộc tính phiên bản và chỉ sử dụng nó trong cuộc gọi không đồng bộ của bạn. – Brian
Có, điều đó sẽ có hiệu quả, nhưng tiếc là điều đó đòi hỏi khá nhiều việc tái cấu trúc thêm (thiết kế lại hoàn toàn các lớp miền của tôi). Trong ứng dụng của tôi, tất cả các lớp miền (hơn 100 lớp) mở rộng lớp siêu với phiên bản trườngNếu phần quan trọng của chúng được cập nhật với một số quy trình không đồng bộ. Vì vậy, thay đổi tên miền cho lý do cụ thể này sẽ rất "xâm nhập" giải pháp. Trong trường hợp đó, tôi nghĩ rằng sẽ dễ dàng hơn để ghi đè lên lớp DefaultFlushEntityEventListener hibernate với khả năng biến phiên bản tăng lên trong một số trường hợp (nhưng điều đó có nghĩa là "phân nhánh" ngủ đông). – Palladium