Search in sources :

Example 11 with CollectionType

use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.

the class IndexNode method resolve.

@Override
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent, AST parentPredicate) throws SemanticException {
    if (isResolved()) {
        return;
    }
    FromReferenceNode collectionNode = (FromReferenceNode) getFirstChild();
    SessionFactoryHelper sessionFactoryHelper = getSessionFactoryHelper();
    // Fully resolve the map reference, create implicit joins.
    collectionNode.resolveIndex(this);
    Type type = collectionNode.getDataType();
    if (!type.isCollectionType()) {
        throw new SemanticException("The [] operator cannot be applied to type " + type.toString());
    }
    String collectionRole = ((CollectionType) type).getRole();
    QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection(collectionRole);
    if (!queryableCollection.hasIndex()) {
        throw new QueryException("unindexed fromElement beforeQuery []: " + collectionNode.getPath());
    }
    // Generate the inner join -- The elements need to be joined to the collection they are in.
    FromElement fromElement = collectionNode.getFromElement();
    String elementTable = fromElement.getTableAlias();
    FromClause fromClause = fromElement.getFromClause();
    String path = collectionNode.getPath();
    FromElement elem = fromClause.findCollectionJoin(path);
    if (elem == null) {
        FromElementFactory factory = new FromElementFactory(fromClause, fromElement, path);
        elem = factory.createCollectionElementsJoin(queryableCollection, elementTable);
        LOG.debugf("No FROM element found for the elements of collection join path %s, created %s", path, elem);
    } else {
        LOG.debugf("FROM element found for collection join path %s", path);
    }
    // The 'from element' that represents the elements of the collection.
    setFromElement(fromElement);
    // Add the condition to the join sequence that qualifies the indexed element.
    AST selector = collectionNode.getNextSibling();
    if (selector == null) {
        throw new QueryException("No index value!");
    }
    // Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
    String collectionTableAlias = elementTable;
    if (elem.getCollectionTableAlias() != null) {
        collectionTableAlias = elem.getCollectionTableAlias();
    }
    // TODO: get SQL rendering out of here, create an AST for the join expressions.
    // Use the SQL generator grammar to generate the SQL text for the index expression.
    JoinSequence joinSequence = fromElement.getJoinSequence();
    String[] indexCols = queryableCollection.getIndexColumnNames();
    if (indexCols.length != 1) {
        throw new QueryException("composite-index appears in []: " + collectionNode.getPath());
    }
    SqlGenerator gen = new SqlGenerator(getSessionFactoryHelper().getFactory());
    try {
        //TODO: used to be exprNoParens! was this needed?
        gen.simpleExpr(selector);
    } catch (RecognitionException e) {
        throw new QueryException(e.getMessage(), e);
    }
    String selectorExpression = gen.getSQL();
    joinSequence.addCondition(collectionTableAlias + '.' + indexCols[0] + " = " + selectorExpression);
    List<ParameterSpecification> paramSpecs = gen.getCollectedParameters();
    if (paramSpecs != null) {
        switch(paramSpecs.size()) {
            case 0:
                // nothing to do
                break;
            case 1:
                ParameterSpecification paramSpec = paramSpecs.get(0);
                paramSpec.setExpectedType(queryableCollection.getIndexType());
                fromElement.setIndexCollectionSelectorParamSpec(paramSpec);
                break;
            default:
                fromElement.setIndexCollectionSelectorParamSpec(new AggregatedIndexCollectionSelectorParameterSpecifications(paramSpecs));
                break;
        }
    }
    // Now, set the text for this node.  It should be the element columns.
    String[] elementColumns = queryableCollection.getElementColumnNames(elementTable);
    setText(elementColumns[0]);
    setResolved();
}
Also used : AST(antlr.collections.AST) ParameterSpecification(org.hibernate.param.ParameterSpecification) SessionFactoryHelper(org.hibernate.hql.internal.ast.util.SessionFactoryHelper) QueryableCollection(org.hibernate.persister.collection.QueryableCollection) CollectionType(org.hibernate.type.CollectionType) Type(org.hibernate.type.Type) QueryException(org.hibernate.QueryException) SqlGenerator(org.hibernate.hql.internal.ast.SqlGenerator) CollectionType(org.hibernate.type.CollectionType) JoinSequence(org.hibernate.engine.internal.JoinSequence) RecognitionException(antlr.RecognitionException) SemanticException(antlr.SemanticException)

Example 12 with CollectionType

use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.

the class AbstractMapComponentNode method resolve.

@Override
public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent, AST parentPredicate) throws SemanticException {
    if (mapFromElement == null) {
        final FromReferenceNode mapReference = getMapReference();
        mapReference.resolve(true, true);
        FromElement sourceFromElement = null;
        if (isAliasRef(mapReference)) {
            final QueryableCollection collectionPersister = mapReference.getFromElement().getQueryableCollection();
            if (Map.class.isAssignableFrom(collectionPersister.getCollectionType().getReturnedClass())) {
                sourceFromElement = mapReference.getFromElement();
            }
        } else {
            if (mapReference.getDataType().isCollectionType()) {
                final CollectionType collectionType = (CollectionType) mapReference.getDataType();
                if (Map.class.isAssignableFrom(collectionType.getReturnedClass())) {
                    sourceFromElement = mapReference.getFromElement();
                }
            }
        }
        if (sourceFromElement == null) {
            throw nonMap();
        }
        mapFromElement = sourceFromElement;
    }
    setFromElement(mapFromElement);
    setDataType(resolveType(mapFromElement.getQueryableCollection()));
    this.columns = resolveColumns(mapFromElement.getQueryableCollection());
    initText(this.columns);
    setFirstChild(null);
}
Also used : CollectionType(org.hibernate.type.CollectionType) QueryableCollection(org.hibernate.persister.collection.QueryableCollection)

Example 13 with CollectionType

use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.

the class DotNode method resolve.

public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent, AST parentPredicate) throws SemanticException {
    // If this dot has already been resolved, stop now.
    if (isResolved()) {
        return;
    }
    // Prepare the left hand side and get the data type.
    Type propertyType = prepareLhs();
    if (parent == null && AbstractEntityPersister.ENTITY_CLASS.equals(propertyName)) {
        DeprecationLogger.DEPRECATION_LOGGER.logDeprecationOfClassEntityTypeSelector(getLhs().getPath());
    }
    // this might be a Java constant.
    if (propertyType == null) {
        if (parent == null) {
            getWalker().getLiteralProcessor().lookupConstant(this);
        }
        // stop now... there was a problem resolving the node anyway.
        return;
    }
    if (propertyType.isComponentType()) {
        // The property is a component...
        checkLhsIsNotCollection();
        dereferenceComponent(parent);
        initText();
    } else if (propertyType.isEntityType()) {
        // The property is another class..
        checkLhsIsNotCollection();
        dereferenceEntity((EntityType) propertyType, implicitJoin, classAlias, generateJoin, parent, parentPredicate);
        initText();
    } else if (propertyType.isCollectionType()) {
        // The property is a collection...
        checkLhsIsNotCollection();
        dereferenceCollection((CollectionType) propertyType, implicitJoin, false, classAlias, parent);
    } else {
        // Otherwise, this is a primitive type.
        if (!CollectionProperties.isAnyCollectionProperty(propertyName)) {
            checkLhsIsNotCollection();
        }
        dereferenceType = DereferenceType.PRIMITIVE;
        initText();
    }
    setResolved();
}
Also used : 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)

Example 14 with CollectionType

use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.

the class FromElementFactory method createElementJoin.

FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
    FromElement elem;
    //TODO: always true for now, but not if we later decide to support elements() in the from clause
    implied = true;
    inElementsFunction = true;
    Type elementType = queryableCollection.getElementType();
    if (!elementType.isEntityType()) {
        throw new IllegalArgumentException("Cannot create element join for a collection of non-entities!");
    }
    this.queryableCollection = queryableCollection;
    SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
    FromElement destination = null;
    String tableAlias = null;
    EntityPersister entityPersister = queryableCollection.getElementPersister();
    tableAlias = fromClause.getAliasGenerator().createName(entityPersister.getEntityName());
    String associatedEntityName = entityPersister.getEntityName();
    EntityPersister targetEntityPersister = sfh.requireClassPersister(associatedEntityName);
    // Create the FROM element for the target (the elements of the collection).
    destination = createAndAddFromElement(associatedEntityName, classAlias, targetEntityPersister, (EntityType) queryableCollection.getElementType(), tableAlias);
    // If the join is implied, then don't include sub-classes on the element.
    if (implied) {
        destination.setIncludeSubclasses(false);
    }
    fromClause.addCollectionJoinFromElementByPath(path, destination);
    //		origin.addDestination(destination);
    // Add the query spaces.
    fromClause.getWalker().addQuerySpaces(entityPersister.getQuerySpaces());
    CollectionType type = queryableCollection.getCollectionType();
    String role = type.getRole();
    String roleAlias = origin.getTableAlias();
    String[] targetColumns = sfh.getCollectionElementColumns(role, roleAlias);
    AssociationType elementAssociationType = sfh.getElementAssociationType(type);
    // Create the join element under the from element.
    JoinType joinType = JoinType.INNER_JOIN;
    JoinSequence joinSequence = sfh.createJoinSequence(implied, elementAssociationType, tableAlias, joinType, targetColumns);
    elem = initializeJoin(path, destination, joinSequence, targetColumns, origin, false);
    // The associated entity is implied, but it must be included in the FROM.
    elem.setUseFromFragment(true);
    // The collection alias is the role.
    elem.setCollectionTableAlias(roleAlias);
    return elem;
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) EntityType(org.hibernate.type.EntityType) JoinType(org.hibernate.sql.JoinType) CollectionType(org.hibernate.type.CollectionType) EntityType(org.hibernate.type.EntityType) CompositeType(org.hibernate.type.CompositeType) AssociationType(org.hibernate.type.AssociationType) Type(org.hibernate.type.Type) AssociationType(org.hibernate.type.AssociationType) CollectionType(org.hibernate.type.CollectionType) SessionFactoryHelper(org.hibernate.hql.internal.ast.util.SessionFactoryHelper) JoinType(org.hibernate.sql.JoinType) JoinSequence(org.hibernate.engine.internal.JoinSequence)

Example 15 with CollectionType

use of org.hibernate.type.CollectionType in project hibernate-orm by hibernate.

the class FromElementFactory method createCollection.

public FromElement createCollection(QueryableCollection queryableCollection, String role, JoinType joinType, boolean fetchFlag, boolean indexed) throws SemanticException {
    if (!collection) {
        throw new IllegalStateException("FromElementFactory not initialized for collections!");
    }
    this.inElementsFunction = indexed;
    FromElement elem;
    this.queryableCollection = queryableCollection;
    collectionType = queryableCollection.getCollectionType();
    String roleAlias = fromClause.getAliasGenerator().createName(role);
    // Correlated subqueries create 'special' implied from nodes
    // because correlated subselects can't use an ANSI-style join
    boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied;
    if (explicitSubqueryFromElement) {
        String pathRoot = StringHelper.root(path);
        FromElement origin = fromClause.getFromElement(pathRoot);
        if (origin == null || origin.getFromClause() != fromClause) {
            implied = true;
        }
    }
    // super-duper-classic-parser-regression-testing-mojo-magic...
    if (explicitSubqueryFromElement && DotNode.useThetaStyleImplicitJoins) {
        implied = true;
    }
    Type elementType = queryableCollection.getElementType();
    if (elementType.isEntityType()) {
        // A collection of entities...
        elem = createEntityAssociation(role, roleAlias, joinType);
    } else if (elementType.isComponentType()) {
        // A collection of components...
        JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
        elem = createCollectionJoin(joinSequence, roleAlias);
    } else {
        // A collection of scalar elements...
        JoinSequence joinSequence = createJoinSequence(roleAlias, joinType);
        elem = createCollectionJoin(joinSequence, roleAlias);
    }
    elem.setRole(role);
    elem.setQueryableCollection(queryableCollection);
    // Don't include sub-classes for implied collection joins or subquery joins.
    if (implied) {
        elem.setIncludeSubclasses(false);
    }
    if (explicitSubqueryFromElement) {
        // Treat explict from elements in sub-queries properly.
        elem.setInProjectionList(true);
    }
    if (fetchFlag) {
        elem.setFetch(true);
    }
    return elem;
}
Also used : JoinType(org.hibernate.sql.JoinType) CollectionType(org.hibernate.type.CollectionType) EntityType(org.hibernate.type.EntityType) CompositeType(org.hibernate.type.CompositeType) AssociationType(org.hibernate.type.AssociationType) Type(org.hibernate.type.Type) JoinSequence(org.hibernate.engine.internal.JoinSequence)

Aggregations

CollectionType (org.hibernate.type.CollectionType)26 Type (org.hibernate.type.Type)21 JoinType (org.hibernate.sql.JoinType)10 EntityType (org.hibernate.type.EntityType)10 CollectionPersister (org.hibernate.persister.collection.CollectionPersister)7 AssociationType (org.hibernate.type.AssociationType)7 CompositeType (org.hibernate.type.CompositeType)7 QueryException (org.hibernate.QueryException)5 JoinSequence (org.hibernate.engine.internal.JoinSequence)5 QueryableCollection (org.hibernate.persister.collection.QueryableCollection)5 HibernateException (org.hibernate.HibernateException)3 ComponentType (org.hibernate.type.ComponentType)3 SemanticException (antlr.SemanticException)2 Serializable (java.io.Serializable)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 MappingException (org.hibernate.MappingException)2 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)2 SessionFactoryHelper (org.hibernate.hql.internal.ast.util.SessionFactoryHelper)2 ClassMetadata (org.hibernate.metadata.ClassMetadata)2