如何更改Hibernate´;s的自动持续策略

如何更改Hibernate´;s的自动持续策略,hibernate,jpa,setter,Hibernate,Jpa,Setter,我刚刚注意到,在调用任何save()或update()方法之前,Hibernate实体会自动持久化到数据库(或至少缓存)。对我来说,这是一个非常奇怪的默认行为——但好吧,只要我可以禁用它,就可以了 我遇到的问题是,只有当数据库中的实体仍然具有检索它时的状态(状态“1”)时,我才想更新实体的状态(从状态“1”到状态“2”)。这是为了在另一台服务器更新同一对象时消除并发问题。因此,我创建了一个自定义的NamedQuery,它只会在实体处于预期状态“1”时更新实体。下面是一些伪代码: // Get t

我刚刚注意到,在调用任何
save()
update()
方法之前,Hibernate实体会自动持久化到数据库(或至少缓存)。对我来说,这是一个非常奇怪的默认行为——但好吧,只要我可以禁用它,就可以了

我遇到的问题是,只有当数据库中的实体仍然具有检索它时的状态(状态“1”)时,我才想更新实体的状态(从状态“1”到状态“2”)。这是为了在另一台服务器更新同一对象时消除并发问题。因此,我创建了一个自定义的
NamedQuery
,它只会在实体处于预期状态“1”时更新实体。下面是一些伪代码:

// Get the entity
Entity item = dao.getEntity(); 
item.getState(); // == 1

// Update the entity
item.setState(2); // Here is the problem, this effectively changes the
                  // state of my entity breaking my query that verifies
                  // that state is still == 1.

dao.customUpdate(item); //Returns 0 rows changes since state != 1.

如何确保setter不会更改cache/db中的状态?

Hibernate内置了对目标的支持—它支持使用版本ID或时间戳进行乐观锁定。如果您试图保存对象,而基础数据已更改,hibernate将引发异常。您可以捕获此异常并根据需要进行处理-忽略更新、重试或任何有意义的操作

编辑:我不清楚更新查询是如何工作的,但如果您想继续手动执行此操作,可以在检索对象后将其从会话中逐出。这将为您提供对象在检索时的快照,您可以独立于db/cache进行修改。您可以将其作为比较的一方传递到自定义更新查询中,另一方是持久化值。当查询选择/更新实体时,将从数据库而不是从被逐出的对象中重新读取该实体。然后,更新查询可以将其与收回/修改的值(作为参数传递)进行比较,以查看是否应该进行更新


请参见

您应该设置会话的刷新模式。这样,只有在执行session#flush()之后,会话实体才会被持久化

如果要更新会话缓存或数据库,请执行以下操作:

Bean bean = session.get(Bean.class, bean.getId());
session.setFlushMode(FlushMode.COMMIT);
// Make some changes to bean object.
Bean bean2 = session.get(Bean.class, bean.getId());
Assert.assertFalse(bean.equals(bean1)); // Assuming equals and hashcode are implemented

更新查询如何获取要比较的原始数据?据我所知,所有查询都将透明地使用会话缓存,因此对对象执行的任何测试都将看到更新的状态,甚至在提交/刷新之前。