/** @see LockingStrategy#lock */
  public void lock(
      Serializable id, Object version, Object object, int timeout, SessionImplementor session)
      throws StaleObjectStateException, JDBCException {
    if (!lockable.isVersioned()) {
      throw new HibernateException(
          "write locks via update not supported for non-versioned entities ["
              + lockable.getEntityName()
              + "]");
    }
    // todo : should we additionally check the current isolation mode explicitly?
    SessionFactoryImplementor factory = session.getFactory();
    try {
      PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
      try {
        lockable.getVersionType().nullSafeSet(st, version, 1, session);
        int offset = 2;

        lockable.getIdentifierType().nullSafeSet(st, id, offset, session);
        offset += lockable.getIdentifierType().getColumnSpan(factory);

        if (lockable.isVersioned()) {
          lockable.getVersionType().nullSafeSet(st, version, offset, session);
        }

        int affected = st.executeUpdate();
        if (affected < 0) {
          factory.getStatisticsImplementor().optimisticFailure(lockable.getEntityName());
          throw new StaleObjectStateException(lockable.getEntityName(), id);
        }

      } finally {
        session.getBatcher().closeStatement(st);
      }

    } catch (SQLException sqle) {
      throw session
          .getFactory()
          .getSQLExceptionHelper()
          .convert(
              sqle,
              "could not lock: " + MessageHelper.infoString(lockable, id, session.getFactory()),
              sql);
    }
  }
 /**
  * Construct a locking strategy based on SQL UPDATE statements.
  *
  * @param lockable The metadata for the entity to be locked.
  * @param lockMode Indictates the type of lock to be acquired. Note that read-locks are not valid
  *     for this strategy.
  */
 public UpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
   this.lockable = lockable;
   this.lockMode = lockMode;
   if (lockMode.lessThan(LockMode.UPGRADE)) {
     throw new HibernateException("[" + lockMode + "] not valid for update statement");
   }
   if (!lockable.isVersioned()) {
     log.warn(
         "write locks via update not supported for non-versioned entities ["
             + lockable.getEntityName()
             + "]");
     this.sql = null;
   } else {
     this.sql = generateLockString();
   }
 }
 protected String generateLockString() {
   SessionFactoryImplementor factory = lockable.getFactory();
   SimpleSelect select =
       new SimpleSelect(factory.getDialect())
           .setLockMode(lockMode)
           .setTableName(lockable.getRootTableName())
           .addColumn(lockable.getRootTableIdentifierColumnNames()[0])
           .addCondition(lockable.getRootTableIdentifierColumnNames(), "=?");
   if (lockable.isVersioned()) {
     select.addCondition(lockable.getVersionColumnName(), "=?");
   }
   if (factory.getSettings().isCommentsEnabled()) {
     select.setComment(lockMode + " lock " + lockable.getEntityName());
   }
   return select.toStatementString();
 }
 @Override
 public void lock(
     Serializable id,
     Object version,
     Object object,
     int timeout,
     SharedSessionContractImplementor session) {
   if (!lockable.isVersioned()) {
     throw new HibernateException(
         "["
             + lockMode
             + "] not supported for non-versioned entities ["
             + lockable.getEntityName()
             + "]");
   }
   final EntityEntry entry = session.getPersistenceContext().getEntry(object);
   // Register the EntityIncrementVersionProcess action to run just prior to transaction commit.
   ((EventSource) session)
       .getActionQueue()
       .registerProcess(new EntityIncrementVersionProcess(object, entry));
 }
  /** @see LockingStrategy#lock */
  public void lock(Serializable id, Object version, Object object, SessionImplementor session)
      throws StaleObjectStateException, JDBCException {

    SessionFactoryImplementor factory = session.getFactory();
    try {
      PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
      try {
        lockable.getIdentifierType().nullSafeSet(st, id, 1, session);
        if (lockable.isVersioned()) {
          lockable
              .getVersionType()
              .nullSafeSet(
                  st, version, lockable.getIdentifierType().getColumnSpan(factory) + 1, session);
        }

        ResultSet rs = st.executeQuery();
        try {
          if (!rs.next()) {
            if (factory.getStatistics().isStatisticsEnabled()) {
              factory.getStatisticsImplementor().optimisticFailure(lockable.getEntityName());
            }
            throw new StaleObjectStateException(lockable.getEntityName(), id);
          }
        } finally {
          rs.close();
        }
      } finally {
        session.getBatcher().closeStatement(st);
      }

    } catch (SQLException sqle) {
      throw JDBCExceptionHelper.convert(
          session.getFactory().getSQLExceptionConverter(),
          sqle,
          "could not lock: " + MessageHelper.infoString(lockable, id, session.getFactory()),
          sql);
    }
  }