我刚刚注意到,在调用任何 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 不会更改缓存/数据库中的状态?
最佳答案
Hibernate 内置了对您想要实现的目标的支持 - 它支持使用版本 ID 或时间戳的乐观锁定。如果您尝试保存对象并且底层数据已更改,hibernate 会抛出异常。您可以捕获此异常并根据需要进行处理 - 忽略更新、重试或任何有意义的操作。
参见Optimistic Concurrency Control
编辑:我不清楚您的更新查询是如何工作的,但是如果您想继续手动执行此操作,您可以在检索对象后将其从 session 中逐出。这为您提供了对象在检索时的快照,您可以独立于数据库/缓存进行修改。您可以将其作为比较的一侧传递到自定义更新查询中,另一侧作为持久值。当查询选择/更新实体时,将从数据库中重新读取该实体,而不是从已驱逐的对象中读取。然后,您的更新查询可以将其与您驱逐/修改的值(作为参数传递)进行比较,以查看是否应该完成更新。
关于hibernate - 如何更改 Hibernate 的自动持久策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2885183/