protected void logDebugSequencingConnected() {
   Vector[] sequenceVectors = new Vector[NUMBER_OF_STATES];
   Iterator itConnectedSequences = connectedSequences.iterator();
   while (itConnectedSequences.hasNext()) {
     Sequence sequence = (Sequence) itConnectedSequences.next();
     int stateId = getStateId(sequence.shouldUsePreallocation(), sequence.shouldUseTransaction());
     Vector v = sequenceVectors[stateId];
     if (v == null) {
       v = new Vector();
       sequenceVectors[stateId] = v;
     }
     v.addElement(sequence);
   }
   for (int i = 0; i < NUMBER_OF_STATES; i++) {
     Vector v = sequenceVectors[i];
     if (v != null) {
       getOwnerSession()
           .log(SessionLog.FINEST, SessionLog.SEQUENCING, "sequencing_connected", states[i]);
       for (int j = 0; j < v.size(); j++) {
         Sequence sequence = (Sequence) v.elementAt(j);
         Object[] args = {
           sequence.getName(),
           Integer.toString(sequence.getPreallocationSize()),
           Integer.toString(sequence.getInitialValue())
         };
         getOwnerSession()
             .log(SessionLog.FINEST, SessionLog.SEQUENCING, "sequence_without_state", args);
       }
     }
   }
 }
  /**
   * PUBLIC: Connect to the database using the predefined login. This connects all of the child
   * sessions and expects that they are in a valid state to be connected.
   */
  public void login(String userName, String password) throws DatabaseException {
    // Bug#3440544 Check if logged in already to stop the attempt to login more than once
    if (isLoggedIn) {
      throw ValidationException.alreadyLoggedIn(this.getName());
    } else {
      if (this.eventManager != null) {
        this.eventManager.preLogin(this);
      }
      // Bug 3848021 - ensure the external transaction controller is initialized
      if (!isConnected()) {
        getServerPlatform().initializeExternalTransactionController();
      }

      // Connection all sessions and initialize
      for (Iterator sessionEnum = getSessionsByName().values().iterator();
          sessionEnum.hasNext(); ) {
        DatabaseSessionImpl session = (DatabaseSessionImpl) sessionEnum.next();
        if (session.hasEventManager()) {
          session.getEventManager().preLogin(session);
        }
        session.getDatasourceLogin().setUserName(userName);
        session.getDatasourceLogin().setPassword(password);

        if (!session.isConnected()) {
          session.connect();
        }
      }
      initializeDescriptors();
      this.isLoggedIn = true;
    }
  }
  /**
   * PUBLIC: Return a session broker that behaves as a client session broker. An acquire session
   * broker is done under the covers on each session inside the session broker, and a new broker is
   * returned.
   *
   * <p>NOTE: when finished with the client broker, it should be releases. See
   * releaseClientSessionBroker.
   */
  public SessionBroker acquireClientSessionBroker() {
    log(SessionLog.FINER, SessionLog.CONNECTION, "acquire_client_session_broker");
    SessionBroker clientBroker = copySessionBroker();
    clientBroker.parent = this;
    clientBroker
        .getIdentityMapAccessorInstance()
        .setIdentityMapManager(getIdentityMapAccessorInstance().getIdentityMapManager());
    clientBroker.commitManager = getCommitManager();
    clientBroker.commandManager = getCommandManager();
    clientBroker.externalTransactionController = getExternalTransactionController();
    clientBroker.setServerPlatform(getServerPlatform());
    String sessionName;
    AbstractSession serverSession;
    Iterator names = this.getSessionsByName().keySet().iterator();
    while (names.hasNext()) {
      sessionName = (String) names.next();
      serverSession = getSessionForName(sessionName);
      if (serverSession instanceof org.eclipse.persistence.sessions.server.ServerSession) {
        if (serverSession.getProject().hasIsolatedClasses()) {
          throw ValidationException.isolatedDataNotSupportedInSessionBroker(sessionName);
        }
        clientBroker.internalRegisterSession(
            sessionName,
            ((org.eclipse.persistence.sessions.server.ServerSession) serverSession)
                .acquireClientSession());
      } else {
        throw ValidationException.cannotAcquireClientSessionFromSession();
      }
    }

    clientBroker.initializeSequencing();
    return clientBroker;
  }
 /** Release any locally allocated sequence back to the global sequence pool. */
 void afterCommitInternal(Map localSequences, Accessor accessor) {
   Iterator it = localSequences.entrySet().iterator();
   while (it.hasNext()) {
     Map.Entry entry = (Map.Entry) it.next();
     String seqName = (String) entry.getKey();
     Vector localSequenceForName = (Vector) entry.getValue();
     if (!localSequenceForName.isEmpty()) {
       getPreallocationHandler().setPreallocated(seqName, localSequenceForName);
       // clear all localSequencesForName
       localSequenceForName.clear();
     }
   }
   if (accessor != null) {
     getOwnerSession()
         .log(
             SessionLog.FINEST,
             SessionLog.SEQUENCING,
             "sequencing_afterTransactionCommitted",
             null,
             accessor);
   } else {
     getOwnerSession()
         .log(
             SessionLog.FINEST,
             SessionLog.SEQUENCING,
             "sequencing_afterTransactionCommitted",
             null);
   }
 }
  /**
   * PUBLIC: set the integrityChecker. IntegrityChecker holds all the ClassDescriptor Exceptions.
   */
  public void setIntegrityChecker(IntegrityChecker integrityChecker) {
    super.setIntegrityChecker(integrityChecker);

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      session.setIntegrityChecker(integrityChecker);
    }
  }
  /**
   * PUBLIC: Set the message log.
   *
   * @see #logMessages()
   */
  public void setLog(Writer log) {
    super.setLog(log);

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      session.setLog(log);
    }
  }
  /**
   * PUBLIC: Set the profiler for the session. This allows for performance operations to be
   * profiled.
   */
  public void setProfiler(SessionProfiler profiler) {
    super.setProfiler(profiler);

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      session.setProfiler(profiler);
    }
  }
 /**
  * INTERNAL: Set isSynchronized flag to indicate that members of session broker are synchronized.
  * This method should only be called by setSynchronized method of UnitOfWork obtained from either
  * DatabaseSession Broker or ClientSession Broker.
  */
 public void setSynchronized(boolean synched) {
   if (!isServerSessionBroker()) {
     super.setSynchronized(synched);
     Iterator itSessions = getSessionsByName().values().iterator();
     while (itSessions.hasNext()) {
       ((AbstractSession) itSessions.next()).setSynchronized(synched);
     }
   }
 }
  /** PUBLIC: Return if this session is a server session broker. */
  public boolean isServerSessionBroker() {
    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      if (session.isServerSession()) {
        return true;
      }
    }

    return false;
  }
 /**
  * PUBLIC: Release the session. This does nothing by default, but allows for other sessions such
  * as the ClientSession to do something.
  */
 public void release() {
   if (isClientSessionBroker()) {
     log(SessionLog.FINER, SessionLog.CONNECTION, "releasing_client_session_broker");
   }
   AbstractSession session;
   for (Iterator enumtr = getSessionsByName().values().iterator(); enumtr.hasNext(); ) {
     session = (AbstractSession) enumtr.next();
     session.release();
   }
   super.release();
 }
  protected void initializeStates() {
    states = new State[NUMBER_OF_STATES];

    Iterator itConnectedSequences = connectedSequences.iterator();
    while (itConnectedSequences.hasNext()) {
      Sequence sequence = (Sequence) itConnectedSequences.next();
      State state = getState(sequence.shouldUsePreallocation(), sequence.shouldUseTransaction());
      if (state == null) {
        createState(sequence.shouldUsePreallocation(), sequence.shouldUseTransaction());
      }
    }
  }
 /**
  * PUBLIC: Disconnect from all databases.
  *
  * @exception EclipseLinkException if a transaction is active, you must rollback any active
  *     transaction before logout.
  * @exception DatabaseException the database will also raise an error if their is an active
  *     transaction, or a general error occurs.
  */
 public void logout() throws DatabaseException {
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     DatabaseSessionImpl session = (DatabaseSessionImpl) sessionEnum.next();
     session.logout();
   }
   if (!isClientSessionBroker()) {
     if (hasExternalTransactionController()) {
       getExternalTransactionController().clearSequencingListeners();
     }
   }
   sequencing = null;
   isLoggedIn = false;
 }
 /** INTERNAL: Rollback the transaction on all child sessions. */
 protected void basicRollbackTransaction() throws DatabaseException {
   DatabaseException globalException = null;
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     try {
       session.rollbackTransaction();
     } catch (DatabaseException exception) {
       globalException = exception;
     }
   }
   if (globalException != null) {
     throw globalException;
   }
 }
  /** PUBLIC: Return if all sessions are still connected to the database. */
  public boolean isConnected() {
    if ((getSessionsByName() == null) || (getSessionsByName().isEmpty())) {
      return false;
    }

    for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
      AbstractSession session = (AbstractSession) sessionEnum.next();
      if (!session.isConnected()) {
        return false;
      }
    }

    return true;
  }
 /**
  * INTERNAL: Returns a number of member sessions that require sequencing callback. Always returns
  * 0 if sequencing is not connected.
  */
 public int howManySequencingCallbacks() {
   if (this.isClientSessionBroker()) {
     return getParent().howManySequencingCallbacks();
   } else {
     int nCallbacks = 0;
     Iterator itSessions = getSessionsByName().values().iterator();
     while (itSessions.hasNext()) {
       if (((DatabaseSessionImpl) itSessions.next()).isSequencingCallbackRequired()) {
         nCallbacks++;
       }
     }
     return nCallbacks;
   }
 }
  /**
   * PUBLIC: Register the session under its name. All of the session's descriptors must have already
   * been registered. The session should not be connected and descriptors should not be initialized.
   */
  public void registerSession(String name, AbstractSession session) {
    session.setIsInBroker(true);
    getSessionsByName().put(name, session);
    session.setBroker(this);
    session.setName(name);

    // The keys/classes must also be used as some descriptors may be under multiple classes.
    Iterator descriptors = session.getDescriptors().values().iterator();
    Iterator classes = session.getDescriptors().keySet().iterator();
    while (descriptors.hasNext()) {
      ClassDescriptor descriptor = (ClassDescriptor) descriptors.next();
      Class descriptorClass = (Class) classes.next();
      getSessionNamesByClass().put(descriptorClass, name);
      getDescriptors().put(descriptorClass, descriptor);
    }
  }
  /** INTERNAL: Acquires a special historical session for reading objects as of a past time. */
  public org.eclipse.persistence.sessions.Session acquireHistoricalSession(AsOfClause clause)
      throws ValidationException {
    if (isServerSessionBroker()) {
      throw ValidationException.cannotAcquireHistoricalSession();
    }

    // ? logMessage("acquire_client_session_broker", (Object[])null);
    SessionBroker historicalBroker = copySessionBroker();
    String sessionName;
    AbstractSession session;
    Iterator names = this.getSessionsByName().keySet().iterator();
    while (names.hasNext()) {
      sessionName = (String) names.next();
      session = getSessionForName(sessionName);
      historicalBroker.registerSession(sessionName, session.acquireHistoricalSession(clause));
    }
    return historicalBroker;
  }
  /** PUBLIC: Return true if the pre-defined query is defined on the session. */
  public boolean containsQuery(String queryName) {
    boolean containsQuery = getQueries().containsKey(queryName);
    if (isClientSessionBroker() && (containsQuery == false)) {
      String sessionName = null;
      AbstractSession ssession = null;

      Iterator names = this.getSessionsByName().keySet().iterator();
      while (names.hasNext()) {
        sessionName = (String) names.next();
        ssession = getSessionForName(sessionName);
        if (ssession instanceof org.eclipse.persistence.sessions.server.ClientSession) {
          if (((ClientSession) ssession).getParent().getBroker().containsQuery(queryName)) {
            return true;
          }
        }
      }
    }

    return containsQuery;
  }
  // Bug#3551263  Override getQuery(String name, Vector arguments) in Session search through
  // the server session broker as well
  public DatabaseQuery getQuery(String name, Vector arguments) {
    DatabaseQuery query = super.getQuery(name, arguments);
    if (isClientSessionBroker() && (query == null)) {
      String sessionName = null;
      AbstractSession ssession = null;
      Iterator names = this.getSessionsByName().keySet().iterator();
      while (names.hasNext()) {
        sessionName = (String) names.next();
        ssession = getSessionForName(sessionName);
        if (ssession instanceof org.eclipse.persistence.sessions.server.ClientSession) {
          query = ((ClientSession) ssession).getParent().getBroker().getQuery(name, arguments);
          if (query != null) {
            return query;
          }
        }
      }
    }

    return query;
  }
  /**
   * PUBLIC: Return the query from the session pre-defined queries with the given name. This allows
   * for common queries to be pre-defined, reused and executed by name.
   */
  public DatabaseQuery getQuery(String name) {
    // Bug#3473441 Should always call super first to ensure any change in Session will be reflected
    // here.
    DatabaseQuery query = super.getQuery(name);
    if (isClientSessionBroker() && (query == null)) {
      String sessionName = null;
      AbstractSession ssession = null;
      Iterator names = this.getSessionsByName().keySet().iterator();
      while (names.hasNext()) {
        sessionName = (String) names.next();
        ssession = getSessionForName(sessionName);
        if (ssession instanceof org.eclipse.persistence.sessions.server.ClientSession) {
          query = ((ClientSession) ssession).getParent().getBroker().getQuery(name);
          if (query != null) {
            return query;
          }
        }
      }
    }

    return query;
  }
 /**
  * INTERNAL: This method notifies the accessor that a particular sets of writes has completed.
  * This notification can be used for such thing as flushing the batch mechanism
  */
 public void writesCompleted() {
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     if (!session.isConnected()) {
       throw DatabaseException.databaseAccessorNotConnected();
     }
   }
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     session.writesCompleted();
   }
 }
 /**
  * INTERNAL: Commit the transaction on all child sessions. This assumes that the commit of the
  * transaction will not fail because all of the modification has already taken place and no errors
  * would have occurred.
  */
 protected void basicCommitTransaction() throws DatabaseException {
   // Do one last check it make sure that all sessions are still connected.
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     if (!session.isConnected()) {
       throw DatabaseException.databaseAccessorNotConnected();
     }
   }
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     session.commitTransaction();
   }
 }
  /**
   * INTERNAL: Allow each descriptor to initialize any dependencies on this session. This is done in
   * two passes to allow the inheritance to be resolved first. Normally the descriptors are added
   * before login, then initialized on login.
   */
  public void initializeDescriptors() {
    // ClientSession initializes sequencing during construction,
    // however DatabaseSession and ServerSession normally call initializeSequencing()
    // in initializeDescriptors method.
    // Because initializeDescriptors() is not called for a session-member of a SessionBroker,
    // initializeSequencing() for the sessions should be called here.
    if (!isClientSessionBroker()) {
      for (Iterator enumtr = getSessionsByName().values().iterator(); enumtr.hasNext(); ) {
        DatabaseSessionImpl databaseSession = (DatabaseSessionImpl) enumtr.next();
        databaseSession.initializeSequencing();
      }
      if (hasExternalTransactionController()) {
        getExternalTransactionController().initializeSequencingListeners();
      }
    }
    super.initializeDescriptors();
    // Must reset project options to session broker project, as initialization occurs
    // with local projects.
    for (Iterator enumtr = getSessionsByName().values().iterator(); enumtr.hasNext(); ) {
      DatabaseSessionImpl databaseSession = (DatabaseSessionImpl) enumtr.next();
      if (databaseSession.getProject().hasGenericHistorySupport()) {
        getProject().setHasGenericHistorySupport(true);
      }
      if (databaseSession.getProject().hasIsolatedClasses()) {
        getProject().setHasIsolatedClasses(true);
      }
      if (databaseSession.getProject().hasNonIsolatedUOWClasses()) {
        getProject().setHasNonIsolatedUOWClasses(true);
      }
      getProject()
          .getDefaultReadOnlyClasses()
          .addAll(databaseSession.getProject().getDefaultReadOnlyClasses());
    }

    // ServerSessionBroker doesn't need sequencing.
    // Sequencing should be obtained either from the ClientSessionBroker or directly
    // from the ClientSession.
    if (isServerSessionBroker()) {
      sequencing = null;
    }
  }
  /** INTERNAL: Conform the result if specified. */
  protected Object conformResult(
      Object result,
      UnitOfWorkImpl unitOfWork,
      AbstractRecord arguments,
      boolean buildDirectlyFromRows) {
    if (getSelectionCriteria() != null) {
      ExpressionBuilder builder = getSelectionCriteria().getBuilder();
      builder.setSession(unitOfWork.getRootSession(null));
      builder.setQueryClass(getReferenceClass());
    }

    // If the query is redirected then the collection returned might no longer
    // correspond to the original container policy.  CR#2342-S.M.
    ContainerPolicy cp;
    if (getRedirector() != null) {
      cp = ContainerPolicy.buildPolicyFor(result.getClass());
    } else {
      cp = getContainerPolicy();
    }

    // This code is now a great deal different...  For one, registration is done
    // as part of conforming.  Also, this should only be called if one actually
    // is conforming.
    // First scan the UnitOfWork for conforming instances.
    // This will walk through the entire cache of registered objects.
    // Let p be objects from result not in the cache.
    // Let c be objects from cache.
    // Presently p intersect c = empty set, but later p subset c.
    // By checking cache now doesConform will be called p fewer times.
    Map indexedInterimResult =
        unitOfWork.scanForConformingInstances(
            getSelectionCriteria(), getReferenceClass(), arguments, this);

    Cursor cursor = null;
    // In the case of cursors just conform/register the initially read collection.
    if (cp.isCursorPolicy()) {
      cursor = (Cursor) result;
      cp = ContainerPolicy.buildPolicyFor(ClassConstants.Vector_class);
      // In nested UnitOfWork session might have been session of the parent.
      cursor.setSession(unitOfWork);
      result = cursor.getObjectCollection();
      // for later incremental conforming...
      cursor.setInitiallyConformingIndex(indexedInterimResult);
      cursor.setSelectionCriteriaClone(getSelectionCriteria());
      cursor.setTranslationRow(arguments);
    }

    // Now conform the result from the database.
    // Remove any deleted or changed objects that no longer conform.
    // Deletes will only work for simple queries, queries with or's or anyof's may not return
    // correct results when untriggered indirection is in the model.
    Vector fromDatabase = null;

    // When building directly from rows, one of the performance benefits
    // is that we no longer have to wrap and then unwrap the originals.
    // result is just a vector, not a container of wrapped originals.
    if (buildDirectlyFromRows) {
      Vector rows = (Vector) result;
      fromDatabase = new Vector(rows.size());
      for (int i = 0; i < rows.size(); i++) {
        Object object = rows.elementAt(i);
        // null is placed in the row collection for 1-m joining to filter duplicate rows.
        if (object != null) {
          Object clone =
              conformIndividualResult(
                  object,
                  unitOfWork,
                  arguments,
                  getSelectionCriteria(),
                  indexedInterimResult,
                  buildDirectlyFromRows);
          if (clone != null) {
            fromDatabase.addElement(clone);
          }
        }
      }
    } else {
      fromDatabase = new Vector(cp.sizeFor(result));
      AbstractSession sessionToUse = unitOfWork.getParent();
      for (Object iter = cp.iteratorFor(result); cp.hasNext(iter); ) {
        Object object = cp.next(iter, sessionToUse);
        Object clone =
            conformIndividualResult(
                object,
                unitOfWork,
                arguments,
                getSelectionCriteria(),
                indexedInterimResult,
                buildDirectlyFromRows);
        if (clone != null) {
          fromDatabase.addElement(clone);
        }
      }
    }

    // Now add the unwrapped conforming instances into an appropriate container.
    // Wrapping is done automatically.
    // Make sure a vector of exactly the right size is returned.
    Object conformedResult =
        cp.containerInstance(indexedInterimResult.size() + fromDatabase.size());
    Object eachClone;
    for (Iterator enumtr = indexedInterimResult.values().iterator(); enumtr.hasNext(); ) {
      eachClone = enumtr.next();
      cp.addInto(eachClone, conformedResult, unitOfWork);
    }
    for (Enumeration enumtr = fromDatabase.elements(); enumtr.hasMoreElements(); ) {
      eachClone = enumtr.nextElement();
      cp.addInto(eachClone, conformedResult, unitOfWork);
    }

    if (cursor != null) {
      cursor.setObjectCollection((Vector) conformedResult);

      // For nested UOW must copy all in object collection to
      // initiallyConformingIndex, as some of these could have been from
      // the parent UnitOfWork.
      if (unitOfWork.isNestedUnitOfWork()) {
        for (Enumeration enumtr = cursor.getObjectCollection().elements();
            enumtr.hasMoreElements(); ) {
          Object clone = enumtr.nextElement();
          indexedInterimResult.put(clone, clone);
        }
      }
      return cursor;
    } else {
      return conformedResult;
    }
  }
 /**
  * INTERNAL: Called in the end of beforeCompletion of external transaction sychronization
  * listener. Close the managed sql connection corresponding to the external transaction, if
  * applicable releases accessor.
  */
 public void releaseJTSConnection() {
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     session.releaseJTSConnection();
   }
 }
 /** INTERNAL: Begin the transaction on all child sessions. */
 protected void basicBeginTransaction() throws DatabaseException {
   for (Iterator sessionEnum = getSessionsByName().values().iterator(); sessionEnum.hasNext(); ) {
     AbstractSession session = (AbstractSession) sessionEnum.next();
     session.beginTransaction();
   }
 }
 /**
  * ADVANCED: Answers the past time this session is as of. Only meaningfull for special historical
  * sessions.
  *
  * @return An immutable object representation of the past time. <code>null</code> if no clause
  *     set, or this a regular session.
  * @see org.eclipse.persistence.expressions.AsOfClause
  * @see #acquireSessionAsOf(java.lang.Number)
  * @see #acquireSessionAsOf(java.util.Date)
  * @see #hasAsOfClause
  */
 public AsOfClause getAsOfClause() {
   for (Iterator enumtr = getSessionsByName().values().iterator(); enumtr.hasNext(); ) {
     return ((AbstractSession) enumtr.next()).getAsOfClause();
   }
   return null;
 }
  protected void onConnectAllSequences() {
    connectedSequences = new Vector();
    boolean shouldUseTransaction = false;
    boolean shouldUsePreallocation = false;
    boolean shouldAcquireValueAfterInsert = false;
    Iterator descriptors = getOwnerSession().getDescriptors().values().iterator();
    while (descriptors.hasNext()) {
      ClassDescriptor descriptor = (ClassDescriptor) descriptors.next();
      // Find root sequence, because inheritance needs to be resolved here.
      // TODO: The way we initialize sequencing needs to be in line with descriptor init.
      ClassDescriptor parentDescriptor = descriptor;
      while (!parentDescriptor.usesSequenceNumbers() && parentDescriptor.isChildDescriptor()) {
        ClassDescriptor newDescriptor =
            getOwnerSession()
                .getDescriptor(parentDescriptor.getInheritancePolicy().getParentClass());
        // Avoid issue with error cases of self parent, or null parent.
        if ((newDescriptor == null) || (newDescriptor == parentDescriptor)) {
          break;
        }
        parentDescriptor = newDescriptor;
      }
      if (!parentDescriptor.usesSequenceNumbers()) {
        continue;
      }
      String seqName = parentDescriptor.getSequenceNumberName();
      Sequence sequence = getSequence(seqName);
      if (sequence == null) {
        sequence = new DefaultSequence(seqName);
        getOwnerSession().getDatasourcePlatform().addSequence(sequence);
      }
      // PERF: Initialize the sequence, this avoid having to look it up every time.
      descriptor.setSequence(sequence);
      if (connectedSequences.contains(sequence)) {
        continue;
      }
      try {
        if (sequence instanceof DefaultSequence
            && !connectedSequences.contains(getDefaultSequence())) {
          getDefaultSequence().onConnect(getOwnerSession().getDatasourcePlatform());
          connectedSequences.add(0, getDefaultSequence());
          shouldUseTransaction |= getDefaultSequence().shouldUseTransaction();
          shouldUsePreallocation |= getDefaultSequence().shouldUsePreallocation();
          shouldAcquireValueAfterInsert |= getDefaultSequence().shouldAcquireValueAfterInsert();
        }
        sequence.onConnect(getOwnerSession().getDatasourcePlatform());
        connectedSequences.addElement(sequence);
        shouldUseTransaction |= sequence.shouldUseTransaction();
        shouldUsePreallocation |= sequence.shouldUsePreallocation();
        shouldAcquireValueAfterInsert |= sequence.shouldAcquireValueAfterInsert();
      } catch (RuntimeException ex) {
        // defaultSequence has to disconnect the last
        for (int i = connectedSequences.size() - 1; i >= 0; i--) {
          try {
            Sequence sequenceToDisconnect = (Sequence) connectedSequences.elementAt(i);
            sequenceToDisconnect.onDisconnect(getOwnerSession().getDatasourcePlatform());
          } catch (RuntimeException ex2) {
            // ignore
          }
        }
        connectedSequences = null;
        throw ex;
      }
    }

    if (shouldAcquireValueAfterInsert && !shouldUsePreallocation) {
      whenShouldAcquireValueForAll = AFTER_INSERT;
    } else if (!shouldAcquireValueAfterInsert && shouldUsePreallocation) {
      whenShouldAcquireValueForAll = BEFORE_INSERT;
    }
    atLeastOneSequenceShouldUseTransaction = shouldUseTransaction;
    atLeastOneSequenceShouldUsePreallocation = shouldUsePreallocation;
  }