Pass UniqueSemantic enum to SingleIdLoadPlan#load method and refactoring of ListResultConsumer#consume() method
This commit is contained in:
parent
d1bc4e6a33
commit
d640662435
|
@ -53,6 +53,7 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
|||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.Fetch;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||
|
||||
/**
|
||||
|
@ -233,7 +234,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
|||
}
|
||||
},
|
||||
row -> (L) row[0],
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
if ( results.size() > 1 ) {
|
||||
|
@ -414,7 +415,7 @@ public abstract class AbstractNaturalIdLoader<T> implements NaturalIdLoader<T> {
|
|||
assert row.length == 1;
|
||||
return row[0];
|
||||
},
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
if ( results.isEmpty() ) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
|
@ -165,7 +166,7 @@ public class CollectionElementLoaderByIndex implements Loader {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
if ( list.isEmpty() ) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -202,7 +203,7 @@ public class CollectionLoaderBatchKey implements CollectionLoader {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* Main implementation of CollectionLoader for handling a load of a single collection-key
|
||||
|
@ -135,7 +136,7 @@ public class CollectionLoaderSingleKey implements CollectionLoader {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
return session.getPersistenceContext().getCollection( collectionKey );
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* A one-time use CollectionLoader for applying a sub-select fetch
|
||||
|
@ -96,7 +97,7 @@ public class CollectionLoaderSubSelectFetch implements CollectionLoader {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
final CollectionKey collectionKey = new CollectionKey( attributeMapping.getCollectionDescriptor(), triggerKey );
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.hibernate.sql.exec.spi.JdbcSelect;
|
|||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.internal.RowTransformerDatabaseSnapshotImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.type.IntegerType;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
@ -229,7 +230,7 @@ class DatabaseSnapshotExecutor {
|
|||
}
|
||||
},
|
||||
RowTransformerDatabaseSnapshotImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
final int size = list.size();
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
|||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -321,7 +322,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
|||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.graph.entity.LoadingEntityEntry;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* Batch support for natural-id multi loading
|
||||
|
@ -190,7 +191,7 @@ public class MultiNaturalIdLoadingBatcher {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBinding;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* NaturalIdLoader for simple natural-ids
|
||||
|
@ -181,7 +182,7 @@ public class SimpleNaturalIdLoader<T> extends AbstractNaturalIdLoader<T> {
|
|||
}
|
||||
},
|
||||
row -> row[0],
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
if ( results.size() > 1 ) {
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -147,7 +148,7 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.sql.exec.spi.ExecutionContext;
|
|||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* todo (6.0) : this can generically define a load-by-uk as well. only the SQL AST and `restrictivePart` vary and they are passed as ctor args
|
||||
|
@ -154,8 +155,7 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
|
|||
}
|
||||
},
|
||||
RowTransformerPassThruImpl.instance(),
|
||||
true,
|
||||
singleResultExpected
|
||||
singleResultExpected ? ListResultsConsumer.UniqueSemantic.ASSERT : ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
if ( list.isEmpty() ) {
|
||||
|
|
|
@ -34,6 +34,7 @@ import org.hibernate.sql.exec.spi.Callback;
|
|||
import org.hibernate.sql.exec.spi.ExecutionContext;
|
||||
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
|
||||
import org.hibernate.sql.exec.spi.JdbcSelect;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -127,7 +128,7 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
|
|||
}
|
||||
},
|
||||
row -> row[0],
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
switch ( list.size() ) {
|
||||
|
@ -204,7 +205,7 @@ public class SingleUniqueKeyEntityLoaderStandard<T> implements SingleUniqueKeyEn
|
|||
}
|
||||
},
|
||||
row -> row[0],
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
|
||||
assert list.size() == 1;
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.hibernate.sql.exec.spi.JdbcSelect;
|
|||
import org.hibernate.sql.exec.spi.JdbcSelectExecutor;
|
||||
import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
||||
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.sql.results.spi.RowTransformer;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
|
@ -135,7 +136,7 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
|
|||
jdbcParameterBindings,
|
||||
executionContext,
|
||||
rowTransformer,
|
||||
false
|
||||
ListResultsConsumer.UniqueSemantic.NONE
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.hibernate.sql.results.internal.RowTransformerPassThruImpl;
|
|||
import org.hibernate.sql.results.internal.RowTransformerSingularReturnImpl;
|
||||
import org.hibernate.sql.results.internal.RowTransformerTupleTransformerAdapter;
|
||||
import org.hibernate.sql.results.internal.TupleMetadata;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.sql.results.spi.RowTransformer;
|
||||
|
||||
/**
|
||||
|
@ -85,7 +86,7 @@ public class ConcreteSqmSelectQueryPlan<R> implements SelectQueryPlan<R> {
|
|||
jdbcParameterBindings,
|
||||
SqlOmittingQueryOptions.omitSqlQueryOptions( executionContext, jdbcSelect ),
|
||||
rowTransformer,
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
}
|
||||
finally {
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.hibernate.sql.exec.spi.JdbcSelect;
|
|||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
|
@ -276,7 +277,7 @@ public class MatchingIdSelectionHelper {
|
|||
jdbcParameterBindings,
|
||||
SqlOmittingQueryOptions.omitSqlQueryOptions( executionContext, idSelectJdbcOperation ),
|
||||
row -> row,
|
||||
true
|
||||
ListResultsConsumer.UniqueSemantic.FILTER
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.hibernate.sql.exec.spi.JdbcSelect;
|
|||
import org.hibernate.sql.results.graph.DomainResult;
|
||||
import org.hibernate.sql.results.graph.basic.BasicResult;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
/**
|
||||
|
@ -207,7 +208,7 @@ public abstract class AbstractCteMutationHandler extends AbstractMutationHandler
|
|||
jdbcParameterBindings,
|
||||
SqlOmittingQueryOptions.omitSqlQueryOptions( executionContext, select ),
|
||||
row -> row[0],
|
||||
false
|
||||
ListResultsConsumer.UniqueSemantic.NONE
|
||||
);
|
||||
return ( (Number) list.get( 0 ) ).intValue();
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
|
|||
JdbcParameterBindings jdbcParameterBindings,
|
||||
ExecutionContext executionContext,
|
||||
RowTransformer<R> rowTransformer,
|
||||
boolean uniqueFilter) {
|
||||
ListResultsConsumer.UniqueSemantic uniqueSemantic) {
|
||||
// Only do auto flushing for top level queries
|
||||
return executeQuery(
|
||||
jdbcSelect,
|
||||
|
@ -80,29 +80,7 @@ public class JdbcSelectExecutorStandardImpl implements JdbcSelectExecutor {
|
|||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql ),
|
||||
ListResultsConsumer.instance( uniqueFilter, false )
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> List<R> list(
|
||||
JdbcSelect jdbcSelect,
|
||||
JdbcParameterBindings jdbcParameterBindings,
|
||||
ExecutionContext executionContext,
|
||||
RowTransformer<R> rowTransformer,
|
||||
boolean uniqueFilter,
|
||||
boolean singleResultExpected) {
|
||||
// Only do auto flushing for top level queries
|
||||
return executeQuery(
|
||||
jdbcSelect,
|
||||
jdbcParameterBindings,
|
||||
executionContext,
|
||||
rowTransformer,
|
||||
(sql) -> executionContext.getSession()
|
||||
.getJdbcCoordinator()
|
||||
.getStatementPreparer()
|
||||
.prepareStatement( sql ),
|
||||
ListResultsConsumer.instance( uniqueFilter, singleResultExpected )
|
||||
ListResultsConsumer.instance( uniqueSemantic )
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.stream.Stream;
|
|||
import org.hibernate.Incubating;
|
||||
import org.hibernate.ScrollMode;
|
||||
import org.hibernate.query.spi.ScrollableResultsImplementor;
|
||||
import org.hibernate.sql.results.spi.ListResultsConsumer;
|
||||
import org.hibernate.sql.results.spi.RowTransformer;
|
||||
|
||||
/**
|
||||
|
@ -23,20 +24,12 @@ import org.hibernate.sql.results.spi.RowTransformer;
|
|||
public interface JdbcSelectExecutor {
|
||||
// todo (6.0) : Ideally we'd have a singular place (JdbcServices? ServiceRegistry?) to obtain these executors
|
||||
|
||||
<R> List<R> list(
|
||||
JdbcSelect jdbcSelect,
|
||||
JdbcParameterBindings jdbcParameterBindings,
|
||||
ExecutionContext executionContext,
|
||||
RowTransformer<R> rowTransformer,
|
||||
boolean uniqueFilter);
|
||||
|
||||
<R> List<R> list(
|
||||
JdbcSelect jdbcSelect,
|
||||
JdbcParameterBindings jdbcParameterBindings,
|
||||
ExecutionContext executionContext,
|
||||
RowTransformer<R> rowTransformer,
|
||||
boolean uniqueFilter,
|
||||
boolean onlyOne);
|
||||
ListResultsConsumer.UniqueSemantic uniqueSemantic);
|
||||
|
||||
<R> ScrollableResultsImplementor<R> scroll(
|
||||
JdbcSelect jdbcSelect,
|
||||
|
|
|
@ -30,12 +30,15 @@ public class ListResultsConsumer<R> implements ResultsConsumer<List<R>, R> {
|
|||
private static final ListResultsConsumer NORMAL_INSTANCE = new ListResultsConsumer( UniqueSemantic.NONE );
|
||||
private static final ListResultsConsumer UNIQUE_INSTANCE = new ListResultsConsumer( UniqueSemantic.ASSERT );
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <R> ListResultsConsumer<R> instance(boolean uniqueFilter, boolean singleResultExpected) {
|
||||
if ( singleResultExpected ) {
|
||||
return UNIQUE_INSTANCE;
|
||||
public static <R> ListResultsConsumer<R> instance(UniqueSemantic uniqueSemantic) {
|
||||
switch ( uniqueSemantic ) {
|
||||
case ASSERT:
|
||||
return UNIQUE_INSTANCE;
|
||||
case FILTER:
|
||||
return UNIQUE_FILTER_INSTANCE;
|
||||
default:
|
||||
return NORMAL_INSTANCE;
|
||||
}
|
||||
return uniqueFilter ? UNIQUE_FILTER_INSTANCE : NORMAL_INSTANCE;
|
||||
}
|
||||
|
||||
public enum UniqueSemantic {
|
||||
|
@ -64,14 +67,9 @@ public class ListResultsConsumer<R> implements ResultsConsumer<List<R>, R> {
|
|||
|
||||
final List<R> results = new ArrayList<>();
|
||||
|
||||
if ( uniqueSemantic == UniqueSemantic.NONE ) {
|
||||
while ( rowProcessingState.next() ) {
|
||||
results.add( rowReader.readRow( rowProcessingState, processingOptions ) );
|
||||
rowProcessingState.finishRowProcessing();
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean uniqueRows = false;
|
||||
boolean uniqueRows = false;
|
||||
|
||||
if ( uniqueSemantic != UniqueSemantic.NONE ) {
|
||||
final Class<R> resultJavaType = rowReader.getResultJavaType();
|
||||
if ( resultJavaType != null && !resultJavaType.isArray() ) {
|
||||
final EntityPersister entityDescriptor = session.getFactory().getMetamodel().findEntityDescriptor(
|
||||
|
@ -80,29 +78,28 @@ public class ListResultsConsumer<R> implements ResultsConsumer<List<R>, R> {
|
|||
uniqueRows = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( uniqueRows ) {
|
||||
final List<JavaTypeDescriptor> resultJavaTypeDescriptors = rowReader.getResultJavaTypeDescriptors();
|
||||
assert resultJavaTypeDescriptors.size() == 1;
|
||||
final JavaTypeDescriptor<R> resultJavaTypeDescriptor = resultJavaTypeDescriptors.get( 0 );
|
||||
|
||||
while ( rowProcessingState.next() ) {
|
||||
final R row = rowReader.readRow( rowProcessingState, processingOptions );
|
||||
boolean add = true;
|
||||
if ( uniqueRows ) {
|
||||
assert resultJavaTypeDescriptors.size() == 1;
|
||||
for ( R existingRow : results ) {
|
||||
if ( resultJavaTypeDescriptor.areEqual( existingRow, row ) ) {
|
||||
if ( uniqueSemantic == UniqueSemantic.ASSERT && !rowProcessingState.hasCollectionInitializers() ) {
|
||||
throw new HibernateException(
|
||||
"More than one row with the given identifier was found: " +
|
||||
jdbcValuesSourceProcessingState.getExecutionContext()
|
||||
.getEntityId() +
|
||||
", for class: " +
|
||||
resultJavaType.getName()
|
||||
);
|
||||
}
|
||||
add = false;
|
||||
break;
|
||||
for ( R existingRow : results ) {
|
||||
if ( resultJavaTypeDescriptor.areEqual( existingRow, row ) ) {
|
||||
if ( uniqueSemantic == UniqueSemantic.ASSERT && !rowProcessingState.hasCollectionInitializers() ) {
|
||||
throw new HibernateException(
|
||||
"More than one row with the given identifier was found: " +
|
||||
jdbcValuesSourceProcessingState.getExecutionContext()
|
||||
.getEntityId() +
|
||||
", for class: " +
|
||||
rowReader.getResultJavaType().getName()
|
||||
);
|
||||
}
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( add ) {
|
||||
|
@ -111,6 +108,12 @@ public class ListResultsConsumer<R> implements ResultsConsumer<List<R>, R> {
|
|||
rowProcessingState.finishRowProcessing();
|
||||
}
|
||||
}
|
||||
else {
|
||||
while ( rowProcessingState.next() ) {
|
||||
results.add( rowReader.readRow( rowProcessingState, processingOptions ) );
|
||||
rowProcessingState.finishRowProcessing();
|
||||
}
|
||||
}
|
||||
persistenceContext.initializeNonLazyCollections();
|
||||
jdbcValuesSourceProcessingState.finishUp();
|
||||
return results;
|
||||
|
|
Loading…
Reference in New Issue