/*
 * Hibernate, Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL), version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 */
package org.hibernate.hql.internal.ast.tree;

import org.hibernate.engine.internal.JoinSequence;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.hql.internal.antlr.HqlSqlTokenTypes;
import org.hibernate.hql.internal.ast.HqlSqlWalker;
import org.hibernate.hql.internal.ast.util.SessionFactoryHelper;
import org.hibernate.persister.collection.QueryableCollection;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.persister.entity.Joinable;
import org.hibernate.sql.JoinType;
import org.hibernate.type.EntityType;
import org.hibernate.type.Type;

Author:Steve Ebersole
/** * @author Steve Ebersole */
public class MapKeyEntityFromElement extends FromElement { private final boolean useThetaJoin; public MapKeyEntityFromElement(boolean useThetaJoin) { super(); this.useThetaJoin = useThetaJoin; } @Override public boolean isImplied() { return useThetaJoin; } @Override public int getType() { return useThetaJoin ? HqlSqlTokenTypes.FROM_FRAGMENT : HqlSqlTokenTypes.JOIN_FRAGMENT; } 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, // todo : ever a time when INNER is appropriate? //JoinType.LEFT_OUTER_JOIN, // needs to be an inner join because of how JoinSequence/JoinFragment work - ugh // 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; } }