乐观锁定 - Hibernate和EJB - 使用HQL进行批量更新

时间:2013-07-10 17:39:41

标签: java hibernate ejb entity optimistic-locking

我有一个这样的实体:

  @Entity
  @Table(name = "PERSON_TB") {
  public class Person implements Serializable {

         private static final long serialVersionUID = 3433ba34234aL;

         @Id
         @Column(name = "ID")
         private Long personId;

         @Column(name = "NAME")
         private String name;

         @Column(name = "UPDATE_DATE")
         private Date updatedDate;

         //getters and setters
  }

我有一个生成HQL的代码:

  Update Person p set p.updatedDate = :dt_1 where p.personId = :pid_1,
                      p.updatedDate = :dt_2 where p.personId = :pid_2
                      ....

执行更新的代码:

    @SuppressWarnings("unchecked")
    @TransactionAttribute(TransactionAttributeType.MANDATORY)
    public int executeUpdate(String sql, Map<String, Object> params) {

       Query query = getEntityManager().createQuery(sql);

       for (Entry<String, Object> entry : params.entrySet()) {
          query.setParameter(entry.getKey(), entry.getValue());
       }

       int rows = query.executeUpdate();
       return rows;     
    }

问题:

  1. 乐观锁在这里出现了吗?在上面的例子中,Hibernate是否自动处理乐观锁定(运行HQL而没有会话)?
  2. 如果上述情况不正确,我需要自己实现:我读了Hibernate文档说,我需要使用@Version注释一个字段。但是我应该在表中专门为此添加这个新字段吗?或者我可以指定@Version注释的任何现有字段?这里有什么特别处理吗?
  3. 乐观锁定期间抛出的异常是StaleObjectStateException?因此,当抛出异常时,我可以确定它是一个乐观的锁异常?任何其他用例。原因是,我需要相应地通知用户。

1 个答案:

答案 0 :(得分:4)

  1. 如果您没有使用@Version注释的任何字段,Hibernate无法进行乐观锁定。
  2. 拥有@Version字段的目的正是为了避免实现自己的乐观锁定。 Hibernate将使用@Version注释的字段来实现乐观锁定。它的工作方式是described in the documentation。请注意,更新查询将完全绕过乐观锁定验证。他们可以更新版本字段,但仅限于使用versioned update
  3. exception javadoc解释何时抛出此类异常。