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); }