Search in sources :

Example 36 with QueryException

use of org.hibernate.QueryException in project hibernate-orm by hibernate.

the class IntoClause method visitPropertySpecNodes.

private void visitPropertySpecNodes(AST propertyNode, List types) {
    if (propertyNode == null) {
        return;
    }
    // TODO : we really need to be able to deal with component paths here also;
    // this is difficult because the hql-sql grammar expects all those node types
    // to be FromReferenceNodes.  One potential fix here would be to convert the
    // IntoClause to just use a FromClause/FromElement combo (as a child of the
    // InsertStatement) and move all this logic into the InsertStatement.  That's
    // probably the easiest approach (read: least amount of changes to the grammar
    // and code), but just doesn't feel right as then an insert would contain
    // 2 from-clauses
    String name = propertyNode.getText();
    if (isSuperclassProperty(name)) {
        throw new QueryException("INSERT statements cannot refer to superclass/joined properties [" + name + "]");
    }
    if (!explicitIdInsertion) {
        if (persister.getIdentifierType() instanceof CompositeType) {
            if (componentIds == null) {
                String[] propertyNames = ((CompositeType) persister.getIdentifierType()).getPropertyNames();
                componentIds = new HashSet();
                for (int i = 0; i < propertyNames.length; i++) {
                    componentIds.add(propertyNames[i]);
                }
            }
            if (componentIds.contains(name)) {
                if (explicitComponentIds == null) {
                    explicitComponentIds = new ArrayList(componentIds.size());
                }
                explicitComponentIds.add(name);
                explicitIdInsertion = explicitComponentIds.size() == componentIds.size();
            }
        } else if (name.equals(persister.getIdentifierPropertyName())) {
            explicitIdInsertion = true;
        }
    }
    if (persister.isVersioned()) {
        if (name.equals(persister.getPropertyNames()[persister.getVersionProperty()])) {
            explicitVersionInsertion = true;
        }
    }
    String[] columnNames = persister.toColumns(name);
    renderColumns(columnNames);
    types.add(persister.toType(name));
    // visit width-first, then depth
    visitPropertySpecNodes(propertyNode.getNextSibling(), types);
    visitPropertySpecNodes(propertyNode.getFirstChild(), types);
}
Also used : QueryException(org.hibernate.QueryException) ArrayList(java.util.ArrayList) CompositeType(org.hibernate.type.CompositeType) HashSet(java.util.HashSet)

Example 37 with QueryException

use of org.hibernate.QueryException in project hibernate-orm by hibernate.

the class QueryTranslatorImpl method doCompile.

/**
	 * Performs both filter and non-filter compiling.
	 *
	 * @param replacements   Defined query substitutions.
	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
	 * @param collectionRole the role name of the collection used as the basis for the filter, NULL if this
	 *                       is not a filter.
	 */
private synchronized void doCompile(Map replacements, boolean shallow, String collectionRole) {
    // If the query is already compiled, skip the compilation.
    if (compiled) {
        LOG.debug("compile() : The query is already compiled, skipping...");
        return;
    }
    // Remember the parameters for the compilation.
    this.tokenReplacements = replacements;
    if (tokenReplacements == null) {
        tokenReplacements = new HashMap();
    }
    this.shallowQuery = shallow;
    try {
        // PHASE 1 : Parse the HQL into an AST.
        final HqlParser parser = parse(true);
        // PHASE 2 : Analyze the HQL AST, and produce an SQL AST.
        final HqlSqlWalker w = analyze(parser, collectionRole);
        sqlAst = (Statement) w.getAST();
        if (sqlAst.needsExecutor()) {
            statementExecutor = buildAppropriateStatementExecutor(w);
        } else {
            // PHASE 3 : Generate the SQL.
            generate((QueryNode) sqlAst);
            queryLoader = new QueryLoader(this, factory, w.getSelectClause());
        }
        compiled = true;
    } catch (QueryException qe) {
        if (qe.getQueryString() == null) {
            throw qe.wrapWithQueryString(hql);
        } else {
            throw qe;
        }
    } catch (RecognitionException e) {
        // we do not actually propagate ANTLRExceptions as a cause, so
        // log it here for diagnostic purposes
        LOG.trace("Converted antlr.RecognitionException", e);
        throw QuerySyntaxException.convert(e, hql);
    } catch (ANTLRException e) {
        // we do not actually propagate ANTLRExceptions as a cause, so
        // log it here for diagnostic purposes
        LOG.trace("Converted antlr.ANTLRException", e);
        throw new QueryException(e.getMessage(), hql);
    } catch (IllegalArgumentException e) {
        // translate this into QueryException
        LOG.trace("Converted IllegalArgumentException", e);
        throw new QueryException(e.getMessage(), hql);
    }
    //only needed during compilation phase...
    this.enabledFilters = null;
}
Also used : ANTLRException(antlr.ANTLRException) QueryException(org.hibernate.QueryException) QueryLoader(org.hibernate.loader.hql.QueryLoader) HashMap(java.util.HashMap) RecognitionException(antlr.RecognitionException)

Example 38 with QueryException

use of org.hibernate.QueryException in project hibernate-orm by hibernate.

the class QueryTranslatorImpl method buildAppropriateStatementExecutor.

private StatementExecutor buildAppropriateStatementExecutor(HqlSqlWalker walker) {
    final Statement statement = (Statement) walker.getAST();
    if (walker.getStatementType() == HqlSqlTokenTypes.DELETE) {
        final FromElement fromElement = walker.getFinalFromClause().getFromElement();
        final Queryable persister = fromElement.getQueryable();
        if (persister.isMultiTable()) {
            return new MultiTableDeleteExecutor(walker);
        } else {
            return new DeleteExecutor(walker, persister);
        }
    } else if (walker.getStatementType() == HqlSqlTokenTypes.UPDATE) {
        final FromElement fromElement = walker.getFinalFromClause().getFromElement();
        final Queryable persister = fromElement.getQueryable();
        if (persister.isMultiTable()) {
            // TODO : decide if it is better performance-wise to doAfterTransactionCompletion that check, or to simply use the MultiTableUpdateDelegate
            return new MultiTableUpdateExecutor(walker);
        } else {
            return new BasicExecutor(walker, persister);
        }
    } else if (walker.getStatementType() == HqlSqlTokenTypes.INSERT) {
        return new BasicExecutor(walker, ((InsertStatement) statement).getIntoClause().getQueryable());
    } else {
        throw new QueryException("Unexpected statement type");
    }
}
Also used : MultiTableDeleteExecutor(org.hibernate.hql.internal.ast.exec.MultiTableDeleteExecutor) DeleteExecutor(org.hibernate.hql.internal.ast.exec.DeleteExecutor) QueryException(org.hibernate.QueryException) Statement(org.hibernate.hql.internal.ast.tree.Statement) InsertStatement(org.hibernate.hql.internal.ast.tree.InsertStatement) FromElement(org.hibernate.hql.internal.ast.tree.FromElement) Queryable(org.hibernate.persister.entity.Queryable) MultiTableUpdateExecutor(org.hibernate.hql.internal.ast.exec.MultiTableUpdateExecutor) BasicExecutor(org.hibernate.hql.internal.ast.exec.BasicExecutor) MultiTableDeleteExecutor(org.hibernate.hql.internal.ast.exec.MultiTableDeleteExecutor) InsertStatement(org.hibernate.hql.internal.ast.tree.InsertStatement)

Example 39 with QueryException

use of org.hibernate.QueryException in project hibernate-orm by hibernate.

the class DotNode method dereferenceEntityJoin.

private void dereferenceEntityJoin(String classAlias, EntityType propertyType, boolean impliedJoin, AST parent) throws SemanticException {
    dereferenceType = DereferenceType.ENTITY;
    if (LOG.isDebugEnabled()) {
        LOG.debugf("dereferenceEntityJoin() : generating join for %s in %s (%s) parent = %s", propertyName, getFromElement().getClassName(), classAlias == null ? "<no alias>" : classAlias, ASTUtil.getDebugString(parent));
    }
    // Create a new FROM node for the referenced class.
    String associatedEntityName = propertyType.getAssociatedEntityName();
    String tableAlias = getAliasGenerator().createName(associatedEntityName);
    String[] joinColumns = getColumns();
    String joinPath = getPath();
    if (impliedJoin && getWalker().isInFrom()) {
        joinType = getWalker().getImpliedJoinType();
    }
    FromClause currentFromClause = getWalker().getCurrentFromClause();
    FromElement elem = currentFromClause.findJoinByPath(joinPath);
    ///////////////////////////////////////////////////////////////////////////////
    //
    // This is the piece which recognizes the condition where an implicit join path
    // resolved earlier in a correlated subquery is now being referenced in the
    // outer query.  For 3.0final, we just let this generate a second join (which
    // is exactly how the old parser handles this).  Eventually we need to add this
    // logic back in and complete the logic in FromClause.promoteJoin; however,
    // FromClause.promoteJoin has its own difficulties (see the comments in
    // FromClause.promoteJoin).
    //
    //		if ( elem == null ) {
    //			// see if this joinPath has been used in a "child" FromClause, and if so
    //			// promote that element to the outer query
    //			FromClause currentNodeOwner = getFromElement().getFromClause();
    //			FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath );
    //			if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) {
    //				elem = currentJoinOwner.findJoinByPathLocal( joinPath );
    //				if ( elem != null ) {
    //					currentFromClause.promoteJoin( elem );
    //					// EARLY EXIT!!!
    //					return;
    //				}
    //			}
    //		}
    //
    ///////////////////////////////////////////////////////////////////////////////
    boolean found = elem != null;
    // even though we might find a pre-existing element by join path, we may not be able to reuse it...
    boolean useFoundFromElement = found && canReuse(classAlias, elem);
    if (!useFoundFromElement) {
        // If this is an implied join in a from element, then use the impled join type which is part of the
        // tree parser's state (set by the gramamar actions).
        JoinSequence joinSequence = getSessionFactoryHelper().createJoinSequence(impliedJoin, propertyType, tableAlias, joinType, joinColumns);
        // If the lhs of the join is a "component join", we need to go back to the
        // first non-component-join as the origin to properly link aliases and
        // join columns
        FromElement lhsFromElement = getLhs().getFromElement();
        while (lhsFromElement != null && ComponentJoin.class.isInstance(lhsFromElement)) {
            lhsFromElement = lhsFromElement.getOrigin();
        }
        if (lhsFromElement == null) {
            throw new QueryException("Unable to locate appropriate lhs");
        }
        String role = lhsFromElement.getClassName() + "." + propertyName;
        FromElementFactory factory = new FromElementFactory(currentFromClause, lhsFromElement, joinPath, classAlias, joinColumns, impliedJoin);
        elem = factory.createEntityJoin(associatedEntityName, tableAlias, joinSequence, fetch, getWalker().isInFrom(), propertyType, role, joinPath);
    } else {
        // NOTE : addDuplicateAlias() already performs nullness checks on the alias.
        currentFromClause.addDuplicateAlias(classAlias, elem);
    }
    setImpliedJoin(elem);
    getWalker().addQuerySpaces(elem.getEntityPersister().getQuerySpaces());
    // This 'dot' expression now refers to the resulting from element.
    setFromElement(elem);
}
Also used : QueryException(org.hibernate.QueryException) JoinSequence(org.hibernate.engine.internal.JoinSequence)

Example 40 with QueryException

use of org.hibernate.QueryException in project hibernate-orm by hibernate.

the class DotNode method dereferenceCollection.

private void dereferenceCollection(CollectionType collectionType, boolean implicitJoin, boolean indexed, String classAlias, AST parent) throws SemanticException {
    dereferenceType = DereferenceType.COLLECTION;
    String role = collectionType.getRole();
    //foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness)
    boolean isSizeProperty = getNextSibling() != null && CollectionProperties.isAnyCollectionProperty(getNextSibling().getText());
    if (isSizeProperty) {
        //yuck!
        indexed = true;
    }
    QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection(role);
    String propName = getPath();
    FromClause currentFromClause = getWalker().getCurrentFromClause();
    // If the lhs of the join is a "component join", we need to go back to the
    // first non-component-join as the origin to properly link aliases and
    // join columns
    FromElement lhsFromElement = getLhs().getFromElement();
    while (lhsFromElement != null && ComponentJoin.class.isInstance(lhsFromElement)) {
        lhsFromElement = lhsFromElement.getOrigin();
    }
    if (lhsFromElement == null) {
        throw new QueryException("Unable to locate appropriate lhs");
    }
    // in all other cases, we should use the table alias
    if (getWalker().getStatementType() != SqlTokenTypes.SELECT) {
        if (isFromElementUpdateOrDeleteRoot(lhsFromElement)) {
            // at this point we know we have the 2 conditions above,
            // lets see if we have the mentioned "multi-table" caveat...
            boolean useAlias = false;
            if (getWalker().getStatementType() != SqlTokenTypes.INSERT) {
                final Queryable persister = lhsFromElement.getQueryable();
                if (persister.isMultiTable()) {
                    useAlias = true;
                }
            }
            if (!useAlias) {
                final String lhsTableName = lhsFromElement.getQueryable().getTableName();
                columns = getFromElement().toColumns(lhsTableName, propertyPath, false, true);
            }
        }
    }
    // We do not look for an existing join on the same path, because
    // it makes sense to join twice on the same collection role
    FromElementFactory factory = new FromElementFactory(currentFromClause, lhsFromElement, propName, classAlias, getColumns(), implicitJoin);
    FromElement elem = factory.createCollection(queryableCollection, role, joinType, fetch, indexed);
    LOG.debugf("dereferenceCollection() : Created new FROM element for %s : %s", propName, elem);
    setImpliedJoin(elem);
    // This 'dot' expression now refers to the resulting from element.
    setFromElement(elem);
    if (isSizeProperty) {
        elem.setText("");
        elem.setUseWhereFragment(false);
    }
    if (!implicitJoin) {
        EntityPersister entityPersister = elem.getEntityPersister();
        if (entityPersister != null) {
            getWalker().addQuerySpaces(entityPersister.getQuerySpaces());
        }
    }
    // Always add the collection's query spaces.
    getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces());
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) AbstractEntityPersister(org.hibernate.persister.entity.AbstractEntityPersister) QueryException(org.hibernate.QueryException) Queryable(org.hibernate.persister.entity.Queryable) QueryableCollection(org.hibernate.persister.collection.QueryableCollection)

Aggregations

QueryException (org.hibernate.QueryException)77 Type (org.hibernate.type.Type)20 Test (org.junit.Test)19 Session (org.hibernate.Session)18 Transaction (org.hibernate.Transaction)12 JoinType (org.hibernate.sql.JoinType)12 Queryable (org.hibernate.persister.entity.Queryable)10 CollectionType (org.hibernate.type.CollectionType)10 MappingException (org.hibernate.MappingException)9 QueryableCollection (org.hibernate.persister.collection.QueryableCollection)9 AssociationType (org.hibernate.type.AssociationType)8 HashMap (java.util.HashMap)6 HibernateException (org.hibernate.HibernateException)6 JoinSequence (org.hibernate.engine.internal.JoinSequence)6 EntityType (org.hibernate.type.EntityType)6 AST (antlr.collections.AST)5 Map (java.util.Map)5 SemanticException (antlr.SemanticException)4 ArrayList (java.util.ArrayList)4 FromElement (org.hibernate.hql.internal.ast.tree.FromElement)4