Search in sources :

Example 1 with SessionFactoryHelper

use of org.hibernate.hql.internal.ast.util.SessionFactoryHelper in project hibernate-orm by hibernate.

the class FromElementFactory method createManyToMany.

private FromElement createManyToMany(String role, String associatedEntityName, String roleAlias, Queryable entityPersister, EntityType type, JoinType 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;
}
Also used : SessionFactoryHelper(org.hibernate.hql.internal.ast.util.SessionFactoryHelper) JoinSequence(org.hibernate.engine.internal.JoinSequence)

Example 2 with SessionFactoryHelper

use of org.hibernate.hql.internal.ast.util.SessionFactoryHelper in project hibernate-orm by hibernate.

the class MapKeyEntityFromElement method buildKeyJoin.

public static MapKeyEntityFromElement buildKeyJoin(FromElement collectionFromElement) {
    final HqlSqlWalker walker = collectionFromElement.getWalker();
    final SessionFactoryHelper sfh = walker.getSessionFactoryHelper();
    final SessionFactoryImplementor sf = sfh.getFactory();
    final QueryableCollection collectionPersister = collectionFromElement.getQueryableCollection();
    final Type indexType = collectionPersister.getIndexType();
    if (indexType == null) {
        throw new IllegalArgumentException("Given collection is not indexed");
    }
    if (!indexType.isEntityType()) {
        throw new IllegalArgumentException("Given collection does not have an entity index");
    }
    final EntityType indexEntityType = (EntityType) indexType;
    final EntityPersister indexEntityPersister = (EntityPersister) indexEntityType.getAssociatedJoinable(sf);
    final String rhsAlias = walker.getAliasGenerator().createName(indexEntityPersister.getEntityName());
    final boolean useThetaJoin = collectionFromElement.getJoinSequence().isThetaStyle();
    MapKeyEntityFromElement join = new MapKeyEntityFromElement(useThetaJoin);
    join.initialize(HqlSqlTokenTypes.JOIN_FRAGMENT, ((Joinable) indexEntityPersister).getTableName());
    join.initialize(collectionFromElement.getWalker());
    join.initializeEntity(collectionFromElement.getFromClause(), indexEntityPersister.getEntityName(), indexEntityPersister, indexEntityType, "<map-key-join-" + collectionFromElement.getClassAlias() + ">", rhsAlias);
    // String[] joinColumns = determineJoinColuns( collectionPersister, joinTableAlias );
    // todo : assumes columns, no formulas
    String[] joinColumns = collectionPersister.getIndexColumnNames(collectionFromElement.getCollectionTableAlias());
    JoinSequence joinSequence = sfh.createJoinSequence(useThetaJoin, indexEntityType, rhsAlias, // JoinType.INNER_JOIN,
    collectionFromElement.getJoinSequence().getFirstJoin().getJoinType(), joinColumns);
    join.setJoinSequence(joinSequence);
    join.setOrigin(collectionFromElement, true);
    join.setColumns(joinColumns);
    join.setUseFromFragment(collectionFromElement.useFromFragment());
    join.setUseWhereFragment(collectionFromElement.useWhereFragment());
    walker.addQuerySpaces(indexEntityPersister.getQuerySpaces());
    return join;
}
Also used : EntityPersister(org.hibernate.persister.entity.EntityPersister) SessionFactoryImplementor(org.hibernate.engine.spi.SessionFactoryImplementor) SessionFactoryHelper(org.hibernate.hql.internal.ast.util.SessionFactoryHelper) QueryableCollection(org.hibernate.persister.collection.QueryableCollection) EntityType(org.hibernate.type.EntityType) JoinType(org.hibernate.sql.JoinType) EntityType(org.hibernate.type.EntityType) Type(org.hibernate.type.Type) HqlSqlWalker(org.hibernate.hql.internal.ast.HqlSqlWalker) JoinSequence(org.hibernate.engine.internal.JoinSequence)

Example 3 with SessionFactoryHelper

use of org.hibernate.hql.internal.ast.util.SessionFactoryHelper in project hibernate-orm by hibernate.

the class FromElementFactory method createJoinSequence.

private JoinSequence createJoinSequence(String roleAlias, JoinType joinType) {
    SessionFactoryHelper sessionFactoryHelper = fromClause.getSessionFactoryHelper();
    String[] joinColumns = getColumns();
    if (collectionType == null) {
        throw new IllegalStateException("collectionType is null!");
    }
    return sessionFactoryHelper.createJoinSequence(implied, collectionType, roleAlias, joinType, joinColumns);
}
Also used : SessionFactoryHelper(org.hibernate.hql.internal.ast.util.SessionFactoryHelper)

Example 4 with SessionFactoryHelper

use of org.hibernate.hql.internal.ast.util.SessionFactoryHelper 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 before []: " + 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 5 with SessionFactoryHelper

use of org.hibernate.hql.internal.ast.util.SessionFactoryHelper 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)

Aggregations

SessionFactoryHelper (org.hibernate.hql.internal.ast.util.SessionFactoryHelper)5 JoinSequence (org.hibernate.engine.internal.JoinSequence)4 Type (org.hibernate.type.Type)3 QueryableCollection (org.hibernate.persister.collection.QueryableCollection)2 EntityPersister (org.hibernate.persister.entity.EntityPersister)2 JoinType (org.hibernate.sql.JoinType)2 CollectionType (org.hibernate.type.CollectionType)2 EntityType (org.hibernate.type.EntityType)2 RecognitionException (antlr.RecognitionException)1 SemanticException (antlr.SemanticException)1 AST (antlr.collections.AST)1 QueryException (org.hibernate.QueryException)1 SessionFactoryImplementor (org.hibernate.engine.spi.SessionFactoryImplementor)1 HqlSqlWalker (org.hibernate.hql.internal.ast.HqlSqlWalker)1 SqlGenerator (org.hibernate.hql.internal.ast.SqlGenerator)1 ParameterSpecification (org.hibernate.param.ParameterSpecification)1 AssociationType (org.hibernate.type.AssociationType)1 CompositeType (org.hibernate.type.CompositeType)1