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; }
public void visit(AST node) { // todo : currently expects that the individual with expressions apply to the same sql table // join. // This may not be the case for joined-subclass where the property values // might be coming from different tables in the joined hierarchy. At some // point we should expand this to support that capability. However, that has // some difficulties: // 1) the biggest is how to handle ORs when the individual comparisons are // linked to different sql joins. // 2) here we would need to track each comparison individually, along with // the join alias to which it applies and then pass that information // back to the FromElement so it can pass it along to the JoinSequence if (node instanceof DotNode) { DotNode dotNode = (DotNode) node; FromElement fromElement = dotNode.getFromElement(); if (referencedFromElement != null) { if (fromElement != referencedFromElement) { throw new HibernateException( "with-clause referenced two different from-clause elements"); } } else { referencedFromElement = fromElement; joinAlias = extractAppliedAlias(dotNode); // todo : temporary // needed because currently persister is the one that // creates and renders the join fragments for inheritence // hierarchies... if (!joinAlias.equals(referencedFromElement.getTableAlias())) { throw new HibernateException( "with clause can only reference columns in the driving table"); } } } }
protected void processQuery(AST select, AST query) throws SemanticException { if (log.isDebugEnabled()) { log.debug("processQuery() : " + query.toStringTree()); } try { QueryNode qn = (QueryNode) query; // Was there an explicit select expression? boolean explicitSelect = select != null && select.getNumberOfChildren() > 0; if (!explicitSelect) { // No explicit select expression; render the id and properties // projection lists for every persister in the from clause into // a single 'token node'. // TODO: the only reason we need this stuff now is collection filters, // we should get rid of derived select clause completely! createSelectClauseFromFromClause(qn); } else { // Use the explicitly declared select expression; determine the // return types indicated by each select token useSelectClause(select); } // After that, process the JOINs. // Invoke a delegate to do the work, as this is farily complex. JoinProcessor joinProcessor = new JoinProcessor(astFactory, queryTranslatorImpl); joinProcessor.processJoins(qn, isSubQuery()); // Attach any mapping-defined "ORDER BY" fragments Iterator itr = qn.getFromClause().getProjectionList().iterator(); while (itr.hasNext()) { final FromElement fromElement = (FromElement) itr.next(); // if ( fromElement.isFetch() && fromElement.isCollectionJoin() ) { if (fromElement.isFetch() && fromElement.getQueryableCollection() != null) { // Does the collection referenced by this FromElement // specify an order-by attribute? If so, attach it to // the query's order-by if (fromElement.getQueryableCollection().hasOrdering()) { String orderByFragment = fromElement .getQueryableCollection() .getSQLOrderByString(fromElement.getCollectionTableAlias()); qn.getOrderByClause().addOrderFragment(orderByFragment); } if (fromElement.getQueryableCollection().hasManyToManyOrdering()) { String orderByFragment = fromElement .getQueryableCollection() .getManyToManyOrderByString(fromElement.getTableAlias()); qn.getOrderByClause().addOrderFragment(orderByFragment); } } } } finally { popFromClause(); } }
protected void postProcessDML(RestrictableStatement statement) throws SemanticException { statement.getFromClause().resolve(); FromElement fromElement = (FromElement) statement.getFromClause().getFromElements().get(0); Queryable persister = fromElement.getQueryable(); // Make #@%$^#^&# sure no alias is applied to the table name fromElement.setText(persister.getTableName()); // append any filter fragments; the EMPTY_MAP is used under the assumption that // currently enabled filters should not affect this process if (persister.getDiscriminatorType() != null) { new SyntheticAndFactory(getASTFactory()) .addDiscriminatorWhereFragment( statement, persister, java.util.Collections.EMPTY_MAP, fromElement.getTableAlias()); } }