示例#1
0
 /** Get the order by string required for collection fetching */
 protected static final String orderBy(List associations) throws MappingException {
   StringBuilder buf = new StringBuilder();
   Iterator iter = associations.iterator();
   OuterJoinableAssociation last = null;
   while (iter.hasNext()) {
     OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
     if (oj.getJoinType() == JoinType.LEFT_OUTER_JOIN) { // why does this matter?
       if (oj.getJoinable().isCollection()) {
         final QueryableCollection queryableCollection = (QueryableCollection) oj.getJoinable();
         if (queryableCollection.hasOrdering()) {
           final String orderByString = queryableCollection.getSQLOrderByString(oj.getRHSAlias());
           buf.append(orderByString).append(", ");
         }
       } else {
         // it might still need to apply a collection ordering based on a
         // many-to-many defined order-by...
         if (last != null && last.getJoinable().isCollection()) {
           final QueryableCollection queryableCollection =
               (QueryableCollection) last.getJoinable();
           if (queryableCollection.isManyToMany() && last.isManyToManyWith(oj)) {
             if (queryableCollection.hasManyToManyOrdering()) {
               final String orderByString =
                   queryableCollection.getManyToManyOrderByString(oj.getRHSAlias());
               buf.append(orderByString).append(", ");
             }
           }
         }
       }
     }
     last = oj;
   }
   if (buf.length() > 0) buf.setLength(buf.length() - 2);
   return buf.toString();
 }
示例#2
0
 /**
  * Count the number of instances of Joinable which are actually also instances of Loadable, or are
  * one-to-many associations
  */
 protected static final int countEntityPersisters(List associations) throws MappingException {
   int result = 0;
   Iterator iter = associations.iterator();
   while (iter.hasNext()) {
     OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
     if (oj.getJoinable().consumesEntityAlias()) {
       result++;
     }
   }
   return result;
 }
 /** Get the position of the join with the given alias in the list of joins */
 private static int getPosition(String lhsAlias, List associations) {
   int result = 0;
   for (int i = 0; i < associations.size(); i++) {
     OuterJoinableAssociation oj = (OuterJoinableAssociation) associations.get(i);
     if (oj.getJoinable()
         .consumesEntityAlias() /*|| oj.getJoinable().consumesCollectionAlias() */) {
       if (oj.rhsAlias.equals(lhsAlias)) return result;
       result++;
     }
   }
   return -1;
 }
示例#4
0
 /**
  * Count the number of instances of Joinable which are actually also instances of
  * PersistentCollection which are being fetched by outer join
  */
 protected static final int countCollectionPersisters(List associations) throws MappingException {
   int result = 0;
   Iterator iter = associations.iterator();
   while (iter.hasNext()) {
     OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
     if (oj.getJoinType() == JoinType.LEFT_OUTER_JOIN
         && oj.getJoinable().isCollection()
         && !oj.hasRestriction()) {
       result++;
     }
   }
   return result;
 }
示例#5
0
  /**
   * Add on association (one-to-one, many-to-one, or a collection) to a list of associations to be
   * fetched by outerjoin
   */
  private void addAssociationToJoinTree(
      final AssociationType type,
      final String[] aliasedLhsColumns,
      final String alias,
      final PropertyPath path,
      final int currentDepth,
      final JoinType joinType)
      throws MappingException {

    Joinable joinable = type.getAssociatedJoinable(getFactory());

    // important to generate alias based on size of association collection
    // *before* adding this join to that collection
    String subalias = generateTableAlias(associations.size() + 1, path, joinable);

    // NOTE : it should be fine to continue to pass only filters below
    // (instead of LoadQueryInfluencers) since "from that point on" we
    // only need to worry about restrictions (and not say adding more
    // joins)
    OuterJoinableAssociation assoc =
        new OuterJoinableAssociation(
            path,
            type,
            alias,
            aliasedLhsColumns,
            subalias,
            joinType,
            getWithClause(path),
            hasRestriction(path),
            getFactory(),
            loadQueryInfluencers.getEnabledFilters());
    assoc.validateJoin(path.getFullPath());
    associations.add(assoc);

    int nextDepth = currentDepth + 1;
    //		path = "";
    if (!joinable.isCollection()) {
      if (joinable instanceof OuterJoinLoadable) {
        walkEntityTree((OuterJoinLoadable) joinable, subalias, path, nextDepth);
      }
    } else {
      if (joinable instanceof QueryableCollection) {
        walkCollectionTree((QueryableCollection) joinable, subalias, path, nextDepth);
      }
    }
  }
 public boolean isManyToManyWith(OuterJoinableAssociation other) {
   if (joinable.isCollection()) {
     QueryableCollection persister = (QueryableCollection) joinable;
     if (persister.isManyToMany()) {
       return persister.getElementType() == other.getJoinableType();
     }
   }
   return false;
 }
示例#7
0
  /** Generate a select list of columns containing all properties of the entity classes */
  protected final String selectString(List associations) throws MappingException {

    if (associations.size() == 0) {
      return "";
    } else {
      StringBuilder buf = new StringBuilder(associations.size() * 100);
      int entityAliasCount = 0;
      int collectionAliasCount = 0;
      for (int i = 0; i < associations.size(); i++) {
        OuterJoinableAssociation join = (OuterJoinableAssociation) associations.get(i);
        OuterJoinableAssociation next =
            (i == associations.size() - 1)
                ? null
                : (OuterJoinableAssociation) associations.get(i + 1);
        final Joinable joinable = join.getJoinable();
        final String entitySuffix =
            (suffixes == null || entityAliasCount >= suffixes.length)
                ? null
                : suffixes[entityAliasCount];
        final String collectionSuffix =
            (collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.length)
                ? null
                : collectionSuffixes[collectionAliasCount];
        final String selectFragment =
            joinable.selectFragment(
                next == null ? null : next.getJoinable(),
                next == null ? null : next.getRHSAlias(),
                join.getRHSAlias(),
                entitySuffix,
                collectionSuffix,
                join.getJoinType() == JoinType.LEFT_OUTER_JOIN);
        if (selectFragment.trim().length() > 0) {
          buf.append(", ").append(selectFragment);
        }
        if (joinable.consumesEntityAlias()) entityAliasCount++;
        if (joinable.consumesCollectionAlias() && join.getJoinType() == JoinType.LEFT_OUTER_JOIN)
          collectionAliasCount++;
      }
      return buf.toString();
    }
  }
示例#8
0
 /** Generate a sequence of <tt>LEFT OUTER JOIN</tt> clauses for the given associations. */
 protected final JoinFragment mergeOuterJoins(List associations) throws MappingException {
   JoinFragment outerjoin = getDialect().createOuterJoinFragment();
   Iterator iter = associations.iterator();
   OuterJoinableAssociation last = null;
   while (iter.hasNext()) {
     OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
     if (last != null && last.isManyToManyWith(oj)) {
       oj.addManyToManyJoin(outerjoin, (QueryableCollection) last.getJoinable());
     } else {
       oj.addJoins(outerjoin);
     }
     last = oj;
   }
   last = null;
   return outerjoin;
 }
示例#9
0
  protected void initPersisters(
      final List associations,
      final LockOptions lockOptions,
      final AssociationInitCallback callback)
      throws MappingException {
    final int joins = countEntityPersisters(associations);
    final int collections = countCollectionPersisters(associations);

    collectionOwners = collections == 0 ? null : new int[collections];
    collectionPersisters = collections == 0 ? null : new CollectionPersister[collections];
    collectionSuffixes = BasicLoader.generateSuffixes(joins + 1, collections);

    this.lockOptions = lockOptions;

    persisters = new Loadable[joins];
    aliases = new String[joins];
    owners = new int[joins];
    ownerAssociationTypes = new EntityType[joins];
    lockModeArray = ArrayHelper.fillArray(lockOptions.getLockMode(), joins);

    int i = 0;
    int j = 0;
    Iterator iter = associations.iterator();
    while (iter.hasNext()) {
      final OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
      if (!oj.isCollection()) {

        persisters[i] = (Loadable) oj.getJoinable();
        aliases[i] = oj.getRHSAlias();
        owners[i] = oj.getOwner(associations);
        ownerAssociationTypes[i] = (EntityType) oj.getJoinableType();
        callback.associationProcessed(oj, i);
        i++;

      } else {

        QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();
        if (oj.getJoinType() == JoinType.LEFT_OUTER_JOIN && !oj.hasRestriction()) {
          // it must be a collection fetch
          collectionPersisters[j] = collPersister;
          collectionOwners[j] = oj.getOwner(associations);
          j++;
        }

        if (collPersister.isOneToMany()) {
          persisters[i] = (Loadable) collPersister.getElementPersister();
          aliases[i] = oj.getRHSAlias();
          callback.associationProcessed(oj, i);
          i++;
        }
      }
    }

    if (ArrayHelper.isAllNegative(owners)) owners = null;
    if (collectionOwners != null && ArrayHelper.isAllNegative(collectionOwners)) {
      collectionOwners = null;
    }
  }