如何使用Hibernate 4手动设置@Version字段?

Ant*_* O. 9 hibernate optimistic-locking jpa-2.0 jboss7.x

环境:

我有那个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
}
Run Code Online (Sandbox Code Playgroud)

我有一个列出用户的搜索页面,然后我点击一个用户进行编辑(userId在URL中给出).

在编辑表单中,我在服务器上存储该实体的字段,当我保存我的用户时,我这样做:

User user = entityManager.find(User.class, userId)
user.setLogin(form.getLogin());
user.setVersion(form.getVersion());
user.setUserId(form.getUserId());
entityManager.merge(user);
Run Code Online (Sandbox Code Playgroud)

题:

因此,如果我正确理解使用Hibernate的乐观锁定,如果我在浏览器中打开2个选项卡来编辑同一个用户,那么在第一个选项卡上更新登录,然后在第二个选项卡上登录,我应该有一个OptimisticLockException不应该?

实际上,这不是我的应用程序的情况...我验证,form.getVersion()在这两种情况下返回相同的值,即使在第二次更新中,user.version已经由第一次编辑更新.

我错过了什么吗?

EntityManager生产@RequestScoped(所以我在两个不同的EntityManager时候我尝试合并...).

我试图做一个entityManager.lock(user, LockModeType.OPTIMISTIC_FORCE_INCREMENT)entityManager.merge(...)(这里说),但它并没有帮助.

我正在使用Seam 3和JBoss 7.0.2.Final(使用Hibernate 4).

chk*_*kal 7

我刚刚对此做了一些研究.

这是不允许修改的版本字段根据JPA规范:

JPA 2.0最终规范,第3.4.2节:

实体可以访问其版本字段或属性的状态,或者导出应用程序用于访问版本的方法,但不得修改版本值.除了4.10节中提到的例外,只允许持久性提供程序设置或更新对象中version属性的值.

注意:第4.10节引用了忽略版本属性的批量更新.


Ant*_* O. 6

实际上我已经找到了一种方法来做到这一点......但我认为这并不是很有效(因为还有1个SELECT请求).

User user = entityManager.find(User.class, userId)
user.setLogin(form.getLogin());
user.setVersion(form.getVersion());
user.setUserId(form.getUserId());

entityManager.detach(user);
entityManager.merge(user);
Run Code Online (Sandbox Code Playgroud)

有了entityManager.detach(user),hibernate现在使用我的设置version值而不是自己复制的某个值...