Search in sources :

Example 1 with FromElementFactory

use of org.hibernate.hql.internal.ast.tree.FromElementFactory in project hibernate-orm by hibernate.

the class EntityGraphQueryHint method getFromElements.

private List<FromElement> getFromElements(List attributeNodes, FromElement origin, FromClause fromClause, HqlSqlWalker walker, Map<String, FromElement> explicitFetches) {
    final List<FromElement> fromElements = new ArrayList<FromElement>();
    for (Object obj : attributeNodes) {
        final AttributeNode<?> attributeNode = (AttributeNode<?>) obj;
        final String attributeName = attributeNode.getAttributeName();
        final String className = origin.getClassName();
        // TODO: This is ignored by collection types and probably wrong for entity types.  Presumably it screws
        // with inheritance.
        final String role = className + "." + attributeName;
        final String classAlias = origin.getClassAlias();
        final String originTableAlias = origin.getTableAlias();
        final Type propertyType = origin.getPropertyType(attributeName, attributeName);
        try {
            FromElement fromElement = explicitFetches.get(role);
            boolean explicitFromElement = false;
            if (fromElement == null) {
                if (propertyType.isEntityType()) {
                    final EntityType entityType = (EntityType) propertyType;
                    final String[] columns = origin.toColumns(originTableAlias, attributeName, false);
                    final String tableAlias = walker.getAliasGenerator().createName(entityType.getAssociatedEntityName());
                    final FromElementFactory fromElementFactory = new FromElementFactory(fromClause, origin, attributeName, classAlias, columns, false);
                    final JoinSequence joinSequence = walker.getSessionFactoryHelper().createJoinSequence(false, entityType, tableAlias, JoinType.LEFT_OUTER_JOIN, columns);
                    fromElement = fromElementFactory.createEntityJoin(entityType.getAssociatedEntityName(), tableAlias, joinSequence, true, walker.isInFrom(), entityType, role, null);
                } else if (propertyType.isCollectionType()) {
                    CollectionType collectionType = (CollectionType) propertyType;
                    final String[] columns = origin.toColumns(originTableAlias, attributeName, false);
                    final FromElementFactory fromElementFactory = new FromElementFactory(fromClause, origin, attributeName, classAlias, columns, false);
                    final QueryableCollection queryableCollection = walker.getSessionFactoryHelper().requireQueryableCollection(collectionType.getRole());
                    fromElement = fromElementFactory.createCollection(queryableCollection, collectionType.getRole(), JoinType.LEFT_OUTER_JOIN, true, false);
                }
            } else {
                explicitFromElement = true;
                fromElement.setInProjectionList(true);
                fromElement.setFetch(true);
            }
            if (fromElement != null) {
                if (!explicitFromElement) {
                    fromElements.add(fromElement);
                }
                // recurse into subgraphs
                for (Subgraph<?> subgraph : attributeNode.getSubgraphs().values()) {
                    fromElements.addAll(getFromElements(subgraph.getAttributeNodes(), fromElement, fromClause, walker, explicitFetches));
                }
            }
        } catch (Exception e) {
            throw new QueryException("Could not apply the EntityGraph to the Query!", e);
        }
    }
    return fromElements;
}
Also used : AttributeNode(javax.persistence.AttributeNode) ArrayList(java.util.ArrayList) QueryableCollection(org.hibernate.persister.collection.QueryableCollection) QueryException(org.hibernate.QueryException) EntityType(org.hibernate.type.EntityType) JoinType(org.hibernate.sql.JoinType) CollectionType(org.hibernate.type.CollectionType) EntityType(org.hibernate.type.EntityType) Type(org.hibernate.type.Type) QueryException(org.hibernate.QueryException) ImpliedFromElement(org.hibernate.hql.internal.ast.tree.ImpliedFromElement) FromElement(org.hibernate.hql.internal.ast.tree.FromElement) CollectionType(org.hibernate.type.CollectionType) FromElementFactory(org.hibernate.hql.internal.ast.tree.FromElementFactory) JoinSequence(org.hibernate.engine.internal.JoinSequence)

Example 2 with FromElementFactory

use of org.hibernate.hql.internal.ast.tree.FromElementFactory in project hibernate-orm by hibernate.

the class HqlSqlWalker method createFromJoinElement.

@Override
protected void createFromJoinElement(AST path, AST alias, int joinType, AST fetchNode, AST propertyFetch, AST with) throws SemanticException {
    boolean fetch = fetchNode != null;
    if (fetch && isSubQuery()) {
        throw new QueryException("fetch not allowed in subquery from-elements");
    }
    // the incoming "path" can be either:
    // 1) an implicit join path (join p.address.city)
    // 2) an entity-join (join com.acme.User)
    // 
    // so make the proper interpretation here...
    final EntityPersister entityJoinReferencedPersister = resolveEntityJoinReferencedPersister(path);
    if (entityJoinReferencedPersister != null) {
        // `path` referenced an entity
        final EntityJoinFromElement join = createEntityJoin(entityJoinReferencedPersister, alias, joinType, propertyFetch, with);
        ((FromReferenceNode) path).setFromElement(join);
    } else {
        if (path.getType() != SqlTokenTypes.DOT) {
            throw new SemanticException("Path expected for join!");
        }
        DotNode dot = (DotNode) path;
        JoinType hibernateJoinType = JoinProcessor.toHibernateJoinType(joinType);
        // Tell the dot node about the join type.
        dot.setJoinType(hibernateJoinType);
        dot.setFetch(fetch);
        // Generate an explicit join for the root dot node.   The implied joins will be collected and passed up
        // to the root dot node.
        dot.resolve(true, false, alias == null ? null : alias.getText());
        final FromElement fromElement;
        if (dot.getDataType() != null && dot.getDataType().isComponentType()) {
            if (dot.getDataType().isAnyType()) {
                throw new SemanticException("An AnyType attribute cannot be join fetched");
            // ^^ because the discriminator (aka, the "meta columns") must be known to the SQL in
            // a non-parameterized way.
            }
            FromElementFactory factory = new FromElementFactory(getCurrentFromClause(), dot.getLhs().getFromElement(), dot.getPropertyPath(), alias == null ? null : alias.getText(), null, false);
            fromElement = factory.createComponentJoin((CompositeType) dot.getDataType());
        } else {
            fromElement = dot.getImpliedJoin();
            fromElement.setAllPropertyFetch(propertyFetch != null);
            if (with != null) {
                if (fetch) {
                    throw new SemanticException("with-clause not allowed on fetched associations; use filters");
                }
                handleWithFragment(fromElement, with);
            }
        }
        if (LOG.isDebugEnabled()) {
            LOG.debug("createFromJoinElement() : " + getASTPrinter().showAsString(fromElement, "-- join tree --"));
        }
    }
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) FromReferenceNode(org.hibernate.hql.internal.ast.tree.FromReferenceNode) QueryException(org.hibernate.QueryException) EntityJoinFromElement(org.hibernate.hql.internal.ast.tree.EntityJoinFromElement) DotNode(org.hibernate.hql.internal.ast.tree.DotNode) FromElement(org.hibernate.hql.internal.ast.tree.FromElement) EntityJoinFromElement(org.hibernate.hql.internal.ast.tree.EntityJoinFromElement) JoinType(org.hibernate.sql.JoinType) FromElementFactory(org.hibernate.hql.internal.ast.tree.FromElementFactory) SemanticException(antlr.SemanticException) CompositeType(org.hibernate.type.CompositeType)

Aggregations

QueryException (org.hibernate.QueryException)2 FromElement (org.hibernate.hql.internal.ast.tree.FromElement)2 FromElementFactory (org.hibernate.hql.internal.ast.tree.FromElementFactory)2 JoinType (org.hibernate.sql.JoinType)2 SemanticException (antlr.SemanticException)1 ArrayList (java.util.ArrayList)1 AttributeNode (javax.persistence.AttributeNode)1 JoinSequence (org.hibernate.engine.internal.JoinSequence)1 DotNode (org.hibernate.hql.internal.ast.tree.DotNode)1 EntityJoinFromElement (org.hibernate.hql.internal.ast.tree.EntityJoinFromElement)1 FromReferenceNode (org.hibernate.hql.internal.ast.tree.FromReferenceNode)1 ImpliedFromElement (org.hibernate.hql.internal.ast.tree.ImpliedFromElement)1 QueryableCollection (org.hibernate.persister.collection.QueryableCollection)1 EntityPersister (org.hibernate.persister.entity.EntityPersister)1 CollectionType (org.hibernate.type.CollectionType)1 CompositeType (org.hibernate.type.CompositeType)1 EntityType (org.hibernate.type.EntityType)1 Type (org.hibernate.type.Type)1