private FromElement createManyToMany(
     String role,
     String associatedEntityName,
     String roleAlias,
     Queryable entityPersister,
     EntityType type,
     int joinType)
     throws SemanticException {
   FromElement elem;
   SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
   if (inElementsFunction /*implied*/) {
     // For implied many-to-many, just add the end join.
     JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
     elem = createJoin(associatedEntityName, roleAlias, joinSequence, type, true);
   } else {
     // For an explicit many-to-many relationship, add a second join from the intermediate
     // (many-to-many) table to the destination table.  Also, make sure that the from element's
     // idea of the destination is the destination table.
     String tableAlias =
         fromClause.getAliasGenerator().createName(entityPersister.getEntityName());
     String[] secondJoinColumns = sfh.getCollectionElementColumns(role, roleAlias);
     // Add the second join, the one that ends in the destination table.
     JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
     joinSequence.addJoin(
         sfh.getElementAssociationType(collectionType), tableAlias, joinType, secondJoinColumns);
     elem = createJoin(associatedEntityName, tableAlias, joinSequence, type, false);
     elem.setUseFromFragment(true);
   }
   return elem;
 }
 protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException {
   FromElement fromElement = currentFromClause.addFromElement(filterEntity.getText(), alias);
   FromClause fromClause = fromElement.getFromClause();
   QueryableCollection persister =
       sessionFactoryHelper.getCollectionPersister(filterCollectionRole);
   // Get the names of the columns used to link between the collection
   // owner and the collection elements.
   String[] keyColumnNames = persister.getKeyColumnNames();
   String fkTableAlias =
       persister.isOneToMany()
           ? fromElement.getTableAlias()
           : fromClause.getAliasGenerator().createName(filterCollectionRole);
   JoinSequence join = sessionFactoryHelper.createJoinSequence();
   join.setRoot(persister, fkTableAlias);
   if (!persister.isOneToMany()) {
     join.addJoin(
         (AssociationType) persister.getElementType(),
         fromElement.getTableAlias(),
         JoinFragment.INNER_JOIN,
         persister.getElementColumnNames(fkTableAlias));
   }
   join.addCondition(fkTableAlias, keyColumnNames, " = ?");
   fromElement.setJoinSequence(join);
   fromElement.setFilter(true);
   if (log.isDebugEnabled()) {
     log.debug("createFromFilterElement() : processed filter FROM element.");
   }
   return fromElement;
 }
  /** Used for collection filters */
  private void addFromAssociation(final String elementName, final String collectionRole)
      throws QueryException {
    // q.addCollection(collectionName, collectionRole);
    QueryableCollection persister = getCollectionPersister(collectionRole);
    Type collectionElementType = persister.getElementType();
    if (!collectionElementType.isEntityType()) {
      throw new QueryException("collection of values in filter: " + elementName);
    }

    String[] keyColumnNames = persister.getKeyColumnNames();
    // if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: "
    // + collectionRole);

    String collectionName;
    JoinSequence join = new JoinSequence(getFactory());
    collectionName =
        persister.isOneToMany() ? elementName : createNameForCollection(collectionRole);
    join.setRoot(persister, collectionName);
    if (!persister.isOneToMany()) {
      // many-to-many
      addCollection(collectionName, collectionRole);
      try {
        join.addJoin(
            (AssociationType) persister.getElementType(),
            elementName,
            JoinFragment.INNER_JOIN,
            persister.getElementColumnNames(collectionName));
      } catch (MappingException me) {
        throw new QueryException(me);
      }
    }
    join.addCondition(collectionName, keyColumnNames, " = ?");
    // if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
    EntityType elemType = (EntityType) collectionElementType;
    addFrom(elementName, elemType.getAssociatedEntityName(), join);
  }