是否可以为特定更新关闭休眠版本增量

是否可以为特定更新关闭休眠版本增量

本文介绍了是否可以为特定更新关闭休眠版本增量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以在不使用休眠状态修改实体版本的情况下更新数据库中的实体?

Is it possible update entity in database without modifying version of entity using hibernate?

使用我的Web应用程序,用户可以创建或更新实体.还有另一个异步过程在任何用户操作之后处理"这些实体.如果用户在处理"实体之前打开实体进行更新,但是在处理"之后尝试保存该实体,则用户将获得"OptimisticLockException",并且所有输入的数据都将丢失.但是我想用用户提供的数据覆盖异步过程中更新的数据.

Using my web application users can create or update entities. And where is another asynchronous process which "processes" these entities after any user operation. If user opens entity for update before entity is "processed", but tries to save it after it is "processed", user will get "OptimisticLockException" and all his entered data will be lost. But I would like to overwrite data updated in asynchronous process with user provided data.

代码片断来说明为什么我需要这种行为(JPA + Hibernate):

code snipet to demonstrate why I need such behaviour (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.

我的实体

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

实际上,我有更多的类遇到类似的问题-因此,我正在寻找一些优雅的非侵入式解决方案.

In reality I have much more classes with similar problem - so I am looking for some elegant non intrusive solution.

在我看来,这是很常见的情况.但是我找不到任何有关如何实现这种功能的信息.

It seems to me this is quite usual scenario. But I could not find any information how to achieve such functionality.

推荐答案

使用休眠 Session ( http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/Session.html ) replicate(...)方法.

Hibernate Optimistic Locking can be bypassed using hibernate Session (http://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/Session.html) replicate(...) method.

不增加版本的代码示例:

Example of code which does not increment version:

//Detaching to prevent hibernate to spot dirty fields.
//Otherwise if entity exists in hibernate session replication will be skipped
//and on flush entity will be updated with version increment.
em.detach(entityDb);
someTimeConsumingProcessingOfEntityFields(entityDb);

//Telling hibernate to save without any version modifications.
//Update hapends only if no newer version exists.
//Executes additional query DB to get current version of entity.
hibernateSession.replicate(entity, ReplicationMode.LATEST_VERSION);

我认为此解决方案比本机SQL更新更好,因为:

I think this solution is better than native SQL update, because:

  • 使用ORM映射(注释或* .hbm.xml)(无需在本地查询中重复Java对象<-> DB Tables映射);
  • 无需手动执行刷新(性能);
  • db和休眠缓存处于相同状态,无需从缓存(性能)中逐出实体;
  • 并且您仍然拥有所有ORM提供的功能,例如乐观锁定等...;

这篇关于是否可以为特定更新关闭休眠版本增量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 03:49