HHH-8276 - Integrate LoadPlans into UniqueEntityLoader (PoC)
This commit is contained in:
parent
4defc8a5d6
commit
8638aac01a
|
@ -30,6 +30,7 @@ import java.util.Map;
|
|||
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.sql.Template;
|
||||
|
||||
/**
|
||||
|
@ -51,30 +52,28 @@ public class FilterHelper {
|
|||
* conditions are the values.
|
||||
*
|
||||
* @param filters The map of defined filters.
|
||||
* @param dialect The sql dialect
|
||||
* @param factory The session factory
|
||||
*/
|
||||
public FilterHelper(List filters, SessionFactoryImplementor factory) {
|
||||
public FilterHelper(List<FilterConfiguration> filters, SessionFactoryImplementor factory) {
|
||||
int filterCount = filters.size();
|
||||
filterNames = new String[filterCount];
|
||||
filterConditions = new String[filterCount];
|
||||
filterAutoAliasFlags = new boolean[filterCount];
|
||||
filterAliasTableMaps = new Map[filterCount];
|
||||
Iterator iter = filters.iterator();
|
||||
filterCount = 0;
|
||||
while ( iter.hasNext() ) {
|
||||
for ( final FilterConfiguration filter : filters ) {
|
||||
filterAutoAliasFlags[filterCount] = false;
|
||||
final FilterConfiguration filter = (FilterConfiguration) iter.next();
|
||||
filterNames[filterCount] = filter.getName();
|
||||
filterConditions[filterCount] = filter.getCondition();
|
||||
filterAliasTableMaps[filterCount] = filter.getAliasTableMap(factory);
|
||||
if ((filterAliasTableMaps[filterCount].isEmpty() || isTableFromPersistentClass(filterAliasTableMaps[filterCount])) && filter.useAutoAliasInjection()){
|
||||
filterAliasTableMaps[filterCount] = filter.getAliasTableMap( factory );
|
||||
if ( (filterAliasTableMaps[filterCount].isEmpty() || isTableFromPersistentClass( filterAliasTableMaps[filterCount] )) && filter
|
||||
.useAutoAliasInjection() ) {
|
||||
filterConditions[filterCount] = Template.renderWhereStringTemplate(
|
||||
filter.getCondition(),
|
||||
FilterImpl.MARKER,
|
||||
factory.getDialect(),
|
||||
factory.getSqlFunctionRegistry()
|
||||
);
|
||||
);
|
||||
filterAutoAliasFlags[filterCount] = true;
|
||||
}
|
||||
filterConditions[filterCount] = StringHelper.replace(
|
||||
|
@ -91,8 +90,8 @@ public class FilterHelper {
|
|||
}
|
||||
|
||||
public boolean isAffectedBy(Map enabledFilters) {
|
||||
for ( int i = 0, max = filterNames.length; i < max; i++ ) {
|
||||
if ( enabledFilters.containsKey( filterNames[i] ) ) {
|
||||
for ( String filterName : filterNames ) {
|
||||
if ( enabledFilters.containsKey( filterName ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -106,13 +105,14 @@ public class FilterHelper {
|
|||
}
|
||||
|
||||
public void render(StringBuilder buffer, FilterAliasGenerator aliasGenerator, Map enabledFilters) {
|
||||
if ( filterNames != null && filterNames.length > 0 ) {
|
||||
for ( int i = 0, max = filterNames.length; i < max; i++ ) {
|
||||
if ( enabledFilters.containsKey( filterNames[i] ) ) {
|
||||
final String condition = filterConditions[i];
|
||||
if ( StringHelper.isNotEmpty( condition ) ) {
|
||||
buffer.append(" and " ).append(render(aliasGenerator, i));
|
||||
}
|
||||
if ( CollectionHelper.isEmpty( filterNames ) ) {
|
||||
return;
|
||||
}
|
||||
for ( int i = 0, max = filterNames.length; i < max; i++ ) {
|
||||
if ( enabledFilters.containsKey( filterNames[i] ) ) {
|
||||
final String condition = filterConditions[i];
|
||||
if ( StringHelper.isNotEmpty( condition ) ) {
|
||||
buffer.append( " and " ).append( render( aliasGenerator, i ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,6 +159,10 @@ public final class CollectionHelper {
|
|||
return !isEmpty( map );
|
||||
}
|
||||
|
||||
public static boolean isEmpty(Object[] objects){
|
||||
return objects == null || objects.length==0;
|
||||
}
|
||||
|
||||
public static <X,Y> Map<X, Y> makeCopy(Map<X, Y> map) {
|
||||
final Map<X,Y> copy = mapOfSize( map.size() + 1 );
|
||||
copy.putAll( map );
|
||||
|
|
|
@ -80,6 +80,7 @@ public class CollectionQuerySpaceImpl extends AbstractQuerySpace implements Coll
|
|||
entityQuerySpace,
|
||||
// not sure this 'rhsColumnNames' bit is correct...
|
||||
( (Queryable) indexPersister ).getKeyColumnNames(),
|
||||
null,
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -109,6 +110,7 @@ public class CollectionQuerySpaceImpl extends AbstractQuerySpace implements Coll
|
|||
"index",
|
||||
compositeQuerySpace,
|
||||
null,
|
||||
null,
|
||||
canJoinsBeRequired()
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -135,6 +137,7 @@ public class CollectionQuerySpaceImpl extends AbstractQuerySpace implements Coll
|
|||
"id",
|
||||
entityQuerySpace,
|
||||
( (Queryable) elementPersister ).getKeyColumnNames(),
|
||||
null,
|
||||
canJoinsBeRequired()
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -166,6 +169,7 @@ public class CollectionQuerySpaceImpl extends AbstractQuerySpace implements Coll
|
|||
"elements",
|
||||
compositeQuerySpace,
|
||||
null,
|
||||
null,
|
||||
canJoinsBeRequired()
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.PropertyMapping;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
||||
|
@ -90,6 +91,7 @@ public class CompositeQuerySpaceImpl extends AbstractQuerySpace implements Compo
|
|||
propertyPath,
|
||||
rhs,
|
||||
null,
|
||||
null,
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -123,6 +125,7 @@ public class CompositeQuerySpaceImpl extends AbstractQuerySpace implements Compo
|
|||
(EntityType) attributeDefinition.getType(),
|
||||
sessionFactory()
|
||||
),
|
||||
(EntityType) attributeDefinition.getType(),
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -151,6 +154,7 @@ public class CompositeQuerySpaceImpl extends AbstractQuerySpace implements Compo
|
|||
attributeDefinition.getName(),
|
||||
rhs,
|
||||
( (CollectionType) attributeDefinition.getType() ).getAssociatedJoinable( sessionFactory() ).getKeyColumnNames(),
|
||||
(AssociationType) attributeDefinition.getType(),
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
import org.hibernate.persister.entity.PropertyMapping;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.persister.walking.spi.CompositionDefinition;
|
||||
import org.hibernate.type.AssociationType;
|
||||
import org.hibernate.type.CollectionType;
|
||||
import org.hibernate.type.CompositeType;
|
||||
import org.hibernate.type.EntityType;
|
||||
|
@ -92,6 +93,7 @@ public class EntityQuerySpaceImpl extends AbstractQuerySpace implements Expandin
|
|||
compositionDefinition.getName(),
|
||||
rhs,
|
||||
null,
|
||||
null,
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -123,6 +125,7 @@ public class EntityQuerySpaceImpl extends AbstractQuerySpace implements Expandin
|
|||
(EntityType) attribute.getType(),
|
||||
sessionFactory()
|
||||
),
|
||||
(AssociationType) attribute.getType(),
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -151,6 +154,7 @@ public class EntityQuerySpaceImpl extends AbstractQuerySpace implements Expandin
|
|||
attributeDefinition.getName(),
|
||||
rhs,
|
||||
( (CollectionType) attributeDefinition.getType() ).getAssociatedJoinable( sessionFactory() ).getKeyColumnNames(),
|
||||
(AssociationType) attributeDefinition.getType(),
|
||||
required
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
@ -178,6 +182,7 @@ public class EntityQuerySpaceImpl extends AbstractQuerySpace implements Expandin
|
|||
"id",
|
||||
rhs,
|
||||
null,
|
||||
null,
|
||||
canJoinsBeRequired()
|
||||
);
|
||||
internalGetJoins().add( join );
|
||||
|
|
|
@ -23,11 +23,10 @@
|
|||
*/
|
||||
package org.hibernate.loader.plan2.build.internal.spaces;
|
||||
|
||||
import org.hibernate.QueryException;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.loader.plan2.spi.JoinDefinedByMetadata;
|
||||
import org.hibernate.loader.plan2.spi.QuerySpace;
|
||||
import org.hibernate.persister.walking.spi.AttributeDefinition;
|
||||
import org.hibernate.type.AssociationType;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -40,19 +39,21 @@ public class JoinImpl implements JoinDefinedByMetadata {
|
|||
|
||||
private final String[] rhsColumnNames;
|
||||
private final boolean rightHandSideOptional;
|
||||
private final AssociationType joinedAssociationPropertyType;
|
||||
|
||||
public JoinImpl(
|
||||
QuerySpace leftHandSide,
|
||||
String lhsPropertyName,
|
||||
QuerySpace rightHandSide,
|
||||
String[] rhsColumnNames,
|
||||
AssociationType attributeType,
|
||||
boolean rightHandSideOptional) {
|
||||
this.leftHandSide = leftHandSide;
|
||||
this.lhsPropertyName = lhsPropertyName;
|
||||
this.rightHandSide = rightHandSide;
|
||||
this.rhsColumnNames = rhsColumnNames;
|
||||
this.rightHandSideOptional = rightHandSideOptional;
|
||||
|
||||
this.joinedAssociationPropertyType = attributeType;
|
||||
if ( StringHelper.isEmpty( lhsPropertyName ) ) {
|
||||
throw new IllegalArgumentException( "Incoming 'lhsPropertyName' parameter was empty" );
|
||||
}
|
||||
|
@ -101,4 +102,9 @@ public class JoinImpl implements JoinDefinedByMetadata {
|
|||
public String getJoinedAssociationPropertyName() {
|
||||
return lhsPropertyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AssociationType getJoinedAssociationPropertyType() {
|
||||
return joinedAssociationPropertyType;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.hibernate.loader.plan2.spi.EntityReference;
|
|||
import org.hibernate.loader.plan2.spi.Fetch;
|
||||
import org.hibernate.loader.plan2.spi.FetchSource;
|
||||
import org.hibernate.loader.plan2.spi.Join;
|
||||
import org.hibernate.loader.plan2.spi.JoinDefinedByMetadata;
|
||||
import org.hibernate.loader.plan2.spi.QuerySpace;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.collection.QueryableCollection;
|
||||
|
@ -55,6 +56,7 @@ import org.hibernate.persister.entity.OuterJoinLoadable;
|
|||
import org.hibernate.persister.walking.internal.FetchStrategyHelper;
|
||||
import org.hibernate.sql.JoinFragment;
|
||||
import org.hibernate.sql.JoinType;
|
||||
import org.hibernate.type.AssociationType;
|
||||
|
||||
/**
|
||||
* Helper for implementors of entity and collection based query building based on LoadPlans providing common
|
||||
|
@ -183,11 +185,12 @@ public class LoadQueryJoinAndFetchProcessor {
|
|||
|
||||
final String[] rhsColumnNames = join.resolveNonAliasedRightHandSideJoinConditionColumns();
|
||||
final String rhsTableAlias = aliases.getTableAlias();
|
||||
|
||||
final AssociationType associationType = join instanceof JoinDefinedByMetadata ? ((JoinDefinedByMetadata)join).getJoinedAssociationPropertyType() : null;
|
||||
final String additionalJoinConditions = resolveAdditionalJoinCondition(
|
||||
rhsTableAlias,
|
||||
join.getAnyAdditionalJoinConditions( rhsTableAlias ),
|
||||
(Joinable) rightHandSide.getEntityPersister()
|
||||
(Joinable) rightHandSide.getEntityPersister(),
|
||||
associationType
|
||||
);
|
||||
|
||||
final Joinable joinable = (Joinable) rightHandSide.getEntityPersister();
|
||||
|
@ -202,13 +205,15 @@ public class LoadQueryJoinAndFetchProcessor {
|
|||
);
|
||||
}
|
||||
|
||||
private String resolveAdditionalJoinCondition(String rhsTableAlias, String withClause, Joinable joinable) {
|
||||
private String resolveAdditionalJoinCondition(String rhsTableAlias, String withClause, Joinable joinable, AssociationType associationType) {
|
||||
// turns out that the call to AssociationType#getOnCondition in the initial code really just translates to
|
||||
// calls to the Joinable.filterFragment() method where the Joinable is either the entity or
|
||||
// collection persister
|
||||
final String filter = joinable.filterFragment(
|
||||
rhsTableAlias,
|
||||
buildingParameters.getQueryInfluencers().getEnabledFilters()
|
||||
final String filter = associationType!=null?
|
||||
associationType.getOnCondition( rhsTableAlias, factory, buildingParameters.getQueryInfluencers().getEnabledFilters() ):
|
||||
joinable.filterFragment(
|
||||
rhsTableAlias,
|
||||
buildingParameters.getQueryInfluencers().getEnabledFilters()
|
||||
);
|
||||
|
||||
if ( StringHelper.isEmpty( withClause ) && StringHelper.isEmpty( filter ) ) {
|
||||
|
@ -432,11 +437,13 @@ public class LoadQueryJoinAndFetchProcessor {
|
|||
// }
|
||||
|
||||
{
|
||||
final AssociationType associationType = join instanceof JoinDefinedByMetadata ? ((JoinDefinedByMetadata)join).getJoinedAssociationPropertyType() : null;
|
||||
// add join fragments from the collection table -> element entity table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
final String additionalJoinConditions = resolveAdditionalJoinCondition(
|
||||
elementTableAlias,
|
||||
join.getAnyAdditionalJoinConditions( elementTableAlias ),
|
||||
queryableCollection
|
||||
queryableCollection,
|
||||
associationType
|
||||
);
|
||||
|
||||
final String manyToManyFilter = persister.getManyToManyFilterFragment(
|
||||
|
|
|
@ -33,8 +33,10 @@ import org.hibernate.collection.spi.PersistentCollection;
|
|||
import org.hibernate.engine.spi.PersistenceContext;
|
||||
import org.hibernate.internal.CoreLogging;
|
||||
import org.hibernate.loader.plan2.exec.process.spi.CollectionReferenceInitializer;
|
||||
import org.hibernate.loader.plan2.exec.process.spi.ResultSetProcessingContext;
|
||||
import org.hibernate.loader.plan2.exec.spi.CollectionReferenceAliases;
|
||||
import org.hibernate.loader.plan2.spi.CollectionReference;
|
||||
import org.hibernate.loader.plan2.spi.Fetch;
|
||||
import org.hibernate.pretty.MessageHelper;
|
||||
|
||||
/**
|
||||
|
@ -153,7 +155,12 @@ public class CollectionReferenceInitializerImpl implements CollectionReferenceIn
|
|||
}
|
||||
|
||||
protected Serializable findCollectionOwnerKey(ResultSetProcessingContextImpl context) {
|
||||
return null;
|
||||
ResultSetProcessingContext.EntityReferenceProcessingState ownerState = context.getOwnerProcessingState( (Fetch) collectionReference );
|
||||
|
||||
if(ownerState == null || ownerState.getEntityKey()==null){
|
||||
return null;
|
||||
}
|
||||
return ownerState.getEntityKey().getIdentifier();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.loader.plan2.spi;
|
||||
|
||||
import org.hibernate.type.AssociationType;
|
||||
|
||||
/**
|
||||
* Specialization of a Join that is defined by the metadata.
|
||||
*
|
||||
|
@ -37,4 +39,5 @@ public interface JoinDefinedByMetadata extends Join {
|
|||
* @return The property name
|
||||
*/
|
||||
public String getJoinedAssociationPropertyName();
|
||||
public AssociationType getJoinedAssociationPropertyType();
|
||||
}
|
||||
|
|
|
@ -296,7 +296,8 @@ public class InterceptorTest extends BaseCoreFunctionalTestCase {
|
|||
@Override
|
||||
public String onPrepareStatement(String sql) {
|
||||
assertNotNull( sql );
|
||||
assertTrue( sql.toLowerCase().startsWith( expectedSQLs.poll().toLowerCase() ) );
|
||||
String expectedSql = expectedSQLs.poll().toLowerCase();
|
||||
assertTrue("sql:\n " + sql.toLowerCase() +"\n doesn't start with \n"+expectedSql+"\n", sql.toLowerCase().startsWith( expectedSql ) );
|
||||
return sql;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue