hibernate - 如何更改 Hibernate 的自动持久策略

标签 hibernate jpa setter

我刚刚注意到,在调用任何 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 中逐出。这为您提供了对象在检索时的快照,您可以独立于数据库/缓存进行修改。您可以将其作为比较的一侧传递到自定义更新查询中,另一侧作为持久值。当查询选择/更新实体时,将从数据库中重新读取该实体,而不是从已驱逐的对象中读取。然后,您的更新查询可以将其与您驱逐/修改的值(作为参数传递)进行比较,以查看是否应该完成更新。

参见Session.evict()

关于hibernate - 如何更改 Hibernate 的自动持久策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2885183/

相关文章:

hibernate - Postgresql CITEXT 数据类型问题 JPA Hibernate

C# 在 setter 方法上添加验证

c++ - “Setter”方法不更改属性,但是测试方法输出“test”吗? (以最少的可复制示例重新提交)

java - 从 hibernate 4 升级到 5.2.17 时单表继承中的 org.hibernate.WrongClassException

hibernate - 默认情况下,如何对实体进行 "filter"查询(where 子句)?

java - Hibernate查询没有返回正确的结果

mysql - 将 MySql View 映射到 JPA 实体,使用哪个唯一 ID?

hibernate - Glassfish/Hibernate 保存而不显式调用保存

java - Spring JPA插入连接表实体时不允许NULL

使用或不使用的 PHP Getters/Setter