环境:
我有一个名为 User
的实体:
@Entity
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer userId;
@Version
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "VERSION", length = 19)
private Date version;
@Column(nullable = false, length = 20)
private String login;
// Getters and Setters
}
我有一个搜索页面,列出了用户列表,然后我点击一个用户以编辑它(在URL中提供了userId
)。
在编辑表单中,我将该实体的字段存储在服务器上,当我保存我的用户时,我这样做:
User user = entityManager.find(User.class, userId)
user.setLogin(form.getLogin());
user.setVersion(form.getVersion());
user.setUserId(form.getUserId());
entityManager.merge(user);
问题:
如果我正确地理解了使用 Hibernate 的乐观锁,那么如果我在浏览器中打开两个选项卡以编辑同一个用户,然后在第一个选项卡上更新登录,然后在第二个选项卡上更新登录,我应该会遇到 OptimisticLockException
,对吗?
实际上,在我的应用程序中并不是这样的...... 我验证过,在这两种情况下,form.getVersion()
返回相同的值,即使第二次更新中,user.version
已经被第一个编辑更新了。
我错过了什么吗?
EntityManager
是通过 @RequestScoped
生成的(因此在尝试合并时我使用了两个不同的 EntityManager
)。
我尝试在 entityManager.merge(...)
之前执行 entityManager.lock(user, LockModeType.OPTIMISTIC_FORCE_INCREMENT)
(如此说道),但这没有帮助。
我正在使用 Seam 3 和 JBoss 7.0.2.Final(它使用 Hibernate 4)。
version
字段绑定,但它与我在User
中设置的version
不对应,在WHERE id =?AND version =?
中。我开发了一个FlushInterceptor
,在我的update
函数存在后调用它,并执行entityManager.flush()
。 - Anthony O.