org.hibernate.loader.plan.build.internal.spaces.QuerySpacesImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
The core O/RM functionality as provided by Hibernate
/*
* 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 .
*/
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
*/
public class QuerySpacesImpl implements ExpandingQuerySpaces {
private static final Logger log = CoreLogging.logger( QuerySpacesImpl.class );
private final SessionFactoryImplementor sessionFactory;
private final List roots = new ArrayList();
private final Map querySpaceByUid = new ConcurrentHashMap();
public QuerySpacesImpl(SessionFactoryImplementor sessionFactory) {
this.sessionFactory = sessionFactory;
}
// QuerySpaces impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public List 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 "";
}
@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.
*
* @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() );
}
}
}