title: Implementing Optimistic lock using Hibernate and Spring
body: <p>I am trying to implement Optimistic locking in-order to avoid lost update situation. In my application when two user fetch same record and the first user updates it with some changes. This change is not visible to the second user who view the same record and he makes some changes by himself and updates it. Due to which the first persons change is lost. In-order to prevent this I have written the following but still the issue persist. I am new to this concept, not able to identify the issue.</p>
  
  <p>I have tried to achieve this by reading <a href="http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html" rel="nofollow">doc</a> 11.3.4. Customizing automatic versioning section.</p>
  
  <ul>
  <li><p>The configuration file</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:mvc="http://www.springframework.org/schema/mvc"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="
  http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
  http://www.springframework.org/schema/mvc
  http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"&gt;
  
  &lt;tx:annotation-driven transaction-manager="txManager"/&gt;
  
  &lt;bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&gt;
    &lt;property name="dataSource" ref="dataSource"/&gt;
  &lt;/bean&gt;
  
  &lt;bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"&gt;
    &lt;property name="sessionFactory" ref="sessionFactory"/&gt;
  &lt;/bean&gt;
  
  &lt;bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&gt;
    &lt;property name="dataSource" ref="dataSource"/&gt;
    &lt;property name="annotatedClasses"&gt;
      &lt;list&gt;
          &lt;value&gt;server.bo.Dept&lt;/value&gt;
          &lt;value&gt;server.bo.Emp&lt;/value&gt;
      &lt;/list&gt;
    &lt;/property&gt;
    &lt;property name="hibernateProperties"&gt;
      &lt;props&gt;
          &lt;prop key="hibernate.dialect"&gt;org.hibernate.dialect.SQLServer2008Dialect&lt;/prop&gt;
          &lt;prop key="hibernate.show_sql"&gt;false&lt;/prop&gt;
      &lt;/props&gt;
    &lt;/property&gt;
  &lt;/bean&gt;
  &lt;bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
    &lt;property name="driverClassName" value="net.sourceforge.jtds.jdbc.Driver"/&gt;
    &lt;property name="url" value="${db.url}"/&gt;
    &lt;property name="username" value="${db.username}"/&gt;
    &lt;property name="password" value="${db.password}"/&gt;
  &lt;/bean&gt;
  &lt;bean id="deptDAO" class="server.dao.DeptDAOImpl"&gt;
    &lt;property name="hibernateTemplate" ref="hibernateTemplate"/&gt;
  &lt;/bean&gt;
  &lt;/beans&gt;
  </code></pre></li>
  <li><p>Entity Class</p>
  
  <pre><code>@Entity
  @Table(name = "Dept")
  @org.hibernate.annotations.Entity(dynamicUpdate = true,optimisticLock = OptimisticLockType.ALL)
  public class Dept{
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name = "ID")
      Long id;
  
      @OneToMany(cascade = CascadeType.REMOVE, fetch = FetchType.EAGER, mappedBy = "deptId")
      @Fetch(FetchMode.SELECT)
      @OrderBy(value = "id DESC")
      List&lt;Emp&gt; Emplist;
  
      public Dept() {}
      // Getters and setters
  }
  </code></pre></li>
  <li><p>DAO Impl</p>
  
  <pre><code>public class DeptDAOImpl extends HibernateDaoSupport implements DeptDAO {
      @Transactional(readOnly = true, propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
      public Dept getDeptById(Long id) {
              Object param[] = new Object[]{id};
              String  query = "select d from Dept d where d.id=? and d.deleted='0'";
              List&lt;Dept&gt; deptDetailsList = getHibernateTemplate().find(query,param);
              Dept deptDetails = null;
              if(deptDetailsList !=null &amp;&amp; deptDetailsList .size()&gt;0)
                  deptDetails = (Dept)deptDetailsList.get(0);
              return deptDetails ;
      }
  
      @Transactional(readOnly = false, propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
      public long updateDept(Dept dept) {
              if (dept.getId() == null) { 
                  getSession().save(dept);
              } else {
                  getSession().update(dept);
              }
              if (dept.getEmplist() != null) {
                      final int size = dept.getEmplist().size();
                      for (int i = size - 1; i &gt;= 0; i--) { 
                          Emp emp = dept.getEmplist().get(i);
                          if (emp.getDeptId() == null) {
                              emp.setDeptId(dept.getId());
                      }
                      if (RecordStatus.NEW.equals(emp.getRecordStatus())) {
                          getSession().save(emp);
                      } else if (RecordStatus.DELETED.equals(emp.getRecordStatus())) {
                          getSession().delete(emp);
                      } else if (RecordStatus.MODIFIED.equals(emp.getRecordStatus())) {
                          getSession().update(emp);
                      }
                  }
          }
          return dept.getId();
      }
  }
  </code></pre></li>
  </ul>
  
  <p>Thanks in advance</p>