public LockTableDescriptor(TypeDescriptor type) {
    Assert.condition(type.isDistinctLockTableName(), "Type must support lock table option.");

    this.type = type;

    Assert.condition(
        !StringUtils.isEmpty(type.getTableAlias()), "Type must have a default alias defined.");

    this.tableAlias = type.getTableAlias() + "_lck";
  }
  public long getNextSequence(TypeDescriptor typeDescriptor, Session session) {
    // check if there is an id in the cache
    ConcurrentLinkedQueue cachedIds =
        (ConcurrentLinkedQueue) this.typeDescriptorToIdCache.get(typeDescriptor);

    if (null == cachedIds) {
      typeDescriptorToIdCache.putIfAbsent(typeDescriptor, new ConcurrentLinkedQueue());

      cachedIds = (ConcurrentLinkedQueue) this.typeDescriptorToIdCache.get(typeDescriptor);
    }

    Number cachedId = (Number) cachedIds.poll();
    if (cachedId == null) {
      synchronized (cachedIds) {
        cachedId = (Number) cachedIds.poll();
        if (cachedId == null) {
          List newIds = this.getNextSequenceImpl(typeDescriptor, session);
          Assert.condition(0 < newIds.size());

          // reserve first for own use
          cachedId = (Number) newIds.remove(0);
          cachedIds.addAll(newIds);
        }
      }
    }

    if (trace.isDebugEnabled()) {
      trace.debug("returning unique ID: " + cachedId.longValue());
    }

    return cachedId.longValue();
  }
  private List getNextSequenceImpl(TypeDescriptor typeDescriptor, Session session) {
    Field[] pkFields = typeDescriptor.getPkFields();

    Assert.condition(
        1 == pkFields.length,
        "Automatic PK values are only supported for types with a single PK field.");

    String createPKStmt =
        dbDescriptor.getCreatePKStatement(
            sqlUtils.getSchemaName(), typeDescriptor.getPkSequence(), this.sequenceBatchSize);

    Field field = pkFields[0];
    if (session.isUsingPreparedStatements(typeDescriptor.getType())) {
      PreparedStatement pkStatement = null;
      try {
        Connection connection = session.getConnection();
        PreparedStatement result;
        try {
          result = connection.prepareStatement(createPKStmt);
        } catch (SQLException x) {
          throw new InternalException(x);
        }
        pkStatement = result;
        ResultSet pkQuery = pkStatement.executeQuery();
        List newIds = new LinkedList();
        while (pkQuery.next()) {
          newIds.add(
              DmlManager.getJavaValue(
                  field.getType(),
                  typeDescriptor.getPersistentField(field).getLength(),
                  pkQuery,
                  1,
                  true,
                  false));
        }
        return newIds;
      } catch (SQLException e) {
        throw new InternalException(e);
      } finally {
        QueryUtils.closeStatement(pkStatement);
      }
    } else {
      Statement pkStmt = null;
      try {
        Connection connection = session.getConnection();
        pkStmt = connection.createStatement();
        ResultSet pkQuery = pkStmt.executeQuery(createPKStmt);
        List newIds = new LinkedList();
        while (pkQuery.next()) {
          newIds.add(
              DmlManager.getJavaValue(
                  field.getType(),
                  typeDescriptor.getPersistentField(field).getLength(),
                  pkQuery,
                  1,
                  true,
                  false));
        }
        return newIds;
      } catch (SQLException e) {
        throw new InternalException(e);
      } finally {
        QueryUtils.closeStatement(pkStmt);
      }
    }
  }