/*
 * 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.loader.plan.build.internal.spaces;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreLogging;
import org.hibernate.loader.plan.build.spi.ExpandingCollectionQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingCompositeQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingEntityQuerySpace;
import org.hibernate.loader.plan.build.spi.ExpandingQuerySpaces;
import org.hibernate.loader.plan.spi.QuerySpace;
import org.hibernate.loader.plan.spi.QuerySpaceUidNotRegisteredException;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.persister.entity.EntityPersister;

import org.jboss.logging.Logger;

Author:Steve Ebersole
/** * @author Steve Ebersole */
public class QuerySpacesImpl implements ExpandingQuerySpaces { private static final Logger log = CoreLogging.logger( QuerySpacesImpl.class ); private final SessionFactoryImplementor sessionFactory; private final List<QuerySpace> roots = new ArrayList<QuerySpace>(); private final Map<String,QuerySpace> querySpaceByUid = new ConcurrentHashMap<String, QuerySpace>(); public QuerySpacesImpl(SessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; } // QuerySpaces impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @Override public List<QuerySpace> getRootQuerySpaces() { return roots; } @Override public QuerySpace findQuerySpaceByUid(String uid) { return querySpaceByUid.get( uid ); } @Override public QuerySpace getQuerySpaceByUid(String uid) { final QuerySpace space = findQuerySpaceByUid( uid ); if ( space == null ) { throw new QuerySpaceUidNotRegisteredException( uid ); } return space; } // ExpandingQuerySpaces impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ private int implicitUidBase; @Override public String generateImplicitUid() { return "<gen:" + implicitUidBase++ + ">"; } @Override public ExpandingEntityQuerySpace makeRootEntityQuerySpace(String uid, EntityPersister entityPersister) { final ExpandingEntityQuerySpace space = makeEntityQuerySpace( uid, entityPersister, true ); roots.add( space ); return space; } @Override public ExpandingEntityQuerySpace makeEntityQuerySpace( String uid, EntityPersister entityPersister, boolean canJoinsBeRequired) { checkQuerySpaceDoesNotExist( uid ); // as a temporary fix for HHH-8980 and HHH-8830 we circumvent allowing // inner joins (canJoinsBeRequired) when the persister is part of an // entity inheritance. // // hasSubclasses() is the closest we can come to even knowing if the // entity is part of a hierarchy. But its enough, since if there are no // subclasses we cannot have the case where the attribute to join comes from // a subclass :) // // a better long term fix is to expose whether a joined association attribute // is defined on the class/superClass(es) or on the subClass(es). Attributes // from the subClass(es) should not be inner joined; it is ok to inner join // attributes from the class/superClass(es). final EntityQuerySpaceImpl space = new EntityQuerySpaceImpl( entityPersister, uid, this, canJoinsBeRequired && !entityPersister.getEntityMetamodel().hasSubclasses() ); registerQuerySpace( space ); return space; } @Override public ExpandingCollectionQuerySpace makeRootCollectionQuerySpace(String uid, CollectionPersister collectionPersister) { final ExpandingCollectionQuerySpace space = makeCollectionQuerySpace( uid, collectionPersister, true ); roots.add( space ); return space; } @Override public ExpandingCollectionQuerySpace makeCollectionQuerySpace( String uid, CollectionPersister collectionPersister, boolean canJoinsBeRequired) { checkQuerySpaceDoesNotExist( uid ); final ExpandingCollectionQuerySpace space = new CollectionQuerySpaceImpl( collectionPersister, uid, this, canJoinsBeRequired ); registerQuerySpace( space ); return space; } @Override public ExpandingCompositeQuerySpace makeCompositeQuerySpace( String uid, CompositePropertyMapping compositePropertyMapping, boolean canJoinsBeRequired) { checkQuerySpaceDoesNotExist( uid ); final ExpandingCompositeQuerySpace space = new CompositeQuerySpaceImpl( compositePropertyMapping, uid, this, canJoinsBeRequired ); registerQuerySpace( space ); return space; } @Override public SessionFactoryImplementor getSessionFactory() { return sessionFactory; } private void checkQuerySpaceDoesNotExist(String uid) { if ( querySpaceByUid.containsKey( uid ) ) { throw new IllegalStateException( "Encountered duplicate QuerySpace uid : " + uid ); } }
Feeds a QuerySpace into this spaces group.
Params:
  • querySpace – The space
/** * Feeds a QuerySpace into this spaces group. * * @param querySpace The space */
private void registerQuerySpace(QuerySpace querySpace) { log.debugf( "Adding QuerySpace : uid = %s -> %s]", querySpace.getUid(), querySpace ); final QuerySpace previous = querySpaceByUid.put( querySpace.getUid(), querySpace ); if ( previous != null ) { throw new IllegalStateException( "Encountered duplicate QuerySpace uid : " + querySpace.getUid() ); } } }