Add a migration guide section, replace static executor uses and remove obsolete todos

This commit is contained in:
Christian Beikov 2022-03-28 11:09:28 +02:00
parent 338cd4fed7
commit 13460034fd
15 changed files with 40 additions and 80 deletions

View File

@ -36,7 +36,6 @@ import org.hibernate.sql.ast.tree.select.QuerySpec;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcParameterImpl;
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@ -185,7 +184,7 @@ class DatabaseSnapshotExecutor {
);
assert offset == jdbcParameters.size();
final List<?> list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
final List<?> list = session.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,
jdbcParameterBindings,
new ExecutionContext() {

View File

@ -42,7 +42,6 @@ import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@ -296,7 +295,7 @@ public class MultiIdLoaderStandard<T> implements MultiIdEntityLoader<T> {
subSelectFetchableKeysHandler = null;
}
return JdbcSelectExecutorStandardImpl.INSTANCE.list(
return session.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,
jdbcParameterBindings,
new ExecutionContext() {

View File

@ -28,7 +28,6 @@ import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@ -162,7 +161,7 @@ public class MultiNaturalIdLoadingBatcher {
}
return JdbcSelectExecutorStandardImpl.INSTANCE.list(
return session.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,
jdbcParamBindings,
new ExecutionContext() {

View File

@ -27,7 +27,6 @@ import org.hibernate.sql.ast.SqlAstTranslatorFactory;
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@ -141,7 +140,7 @@ public class SingleIdEntityLoaderDynamicBatch<T> extends SingleIdEntityLoaderSup
jdbcParameterBindings
);
JdbcSelectExecutorStandardImpl.INSTANCE.list(
session.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,
jdbcParameterBindings,
getExecutionContext(

View File

@ -25,7 +25,6 @@ import org.hibernate.sql.ast.tree.expression.JdbcParameter;
import org.hibernate.sql.ast.tree.select.SelectStatement;
import org.hibernate.sql.exec.internal.CallbackImpl;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
import org.hibernate.sql.exec.spi.Callback;
import org.hibernate.sql.exec.spi.ExecutionContext;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
@ -138,7 +137,7 @@ public class SingleIdLoadPlan<T> implements SingleEntityLoadPlan {
final QueryOptions queryOptions = new SimpleQueryOptions( lockOptions, readOnly );
final Callback callback = new CallbackImpl();
final List<T> list = JdbcSelectExecutorStandardImpl.INSTANCE.list(
final List<T> list = session.getJdbcServices().getJdbcSelectExecutor().list(
jdbcSelect,
jdbcParameterBindings,
new ExecutionContext() {

View File

@ -19,9 +19,7 @@ import org.hibernate.query.spi.QueryParameterBindings;
import org.hibernate.query.sql.spi.ParameterOccurrence;
import org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.StandardJdbcMutationExecutor;
import org.hibernate.sql.exec.spi.JdbcMutation;
import org.hibernate.sql.exec.spi.JdbcMutationExecutor;
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.NativeJdbcMutation;
@ -46,8 +44,9 @@ public class NativeNonSelectQueryPlanImpl implements NonSelectQueryPlan {
@Override
public int executeUpdate(DomainQueryExecutionContext executionContext) {
executionContext.getSession().autoFlushIfRequired( affectedTableNames );
BulkOperationCleanupAction.schedule( executionContext.getSession(), affectedTableNames );
final SharedSessionContractImplementor session = executionContext.getSession();
session.autoFlushIfRequired( affectedTableNames );
BulkOperationCleanupAction.schedule( session, affectedTableNames );
final List<JdbcParameterBinder> jdbcParameterBinders;
final JdbcParameterBindings jdbcParameterBindings;
@ -64,7 +63,7 @@ public class NativeNonSelectQueryPlanImpl implements NonSelectQueryPlan {
queryParameterBindings,
parameterList,
jdbcParameterBinders,
executionContext.getSession().getFactory()
session.getFactory()
);
}
@ -74,14 +73,7 @@ public class NativeNonSelectQueryPlanImpl implements NonSelectQueryPlan {
affectedTableNames
);
final JdbcMutationExecutor executor = StandardJdbcMutationExecutor.INSTANCE;
final SharedSessionContractImplementor session = executionContext.getSession();
// todo (6.0): use configurable executor instead?
// final SessionFactoryImplementor factory = session.getFactory();
// final JdbcServices jdbcServices = factory.getJdbcServices();
// return jdbcServices.getJdbcMutationExecutor().execute(
return executor.execute(
return session.getJdbcServices().getJdbcMutationExecutor().execute(
jdbcMutation,
jdbcParameterBindings,
sql -> session

View File

@ -13,7 +13,9 @@ import java.util.List;
import java.util.Set;
import org.hibernate.ScrollMode;
import org.hibernate.engine.jdbc.spi.JdbcServices;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.EmptyScrollableResults;
import org.hibernate.query.results.ResultSetMapping;
import org.hibernate.query.spi.DomainQueryExecutionContext;
@ -23,11 +25,9 @@ import org.hibernate.query.sql.spi.NativeSelectQueryPlan;
import org.hibernate.query.sql.spi.ParameterOccurrence;
import org.hibernate.query.sqm.internal.SqmJdbcExecutionContextAdapter;
import org.hibernate.sql.exec.internal.JdbcParameterBindingsImpl;
import org.hibernate.sql.exec.internal.JdbcSelectExecutorStandardImpl;
import org.hibernate.sql.exec.spi.JdbcParameterBinder;
import org.hibernate.sql.exec.spi.JdbcParameterBindings;
import org.hibernate.sql.exec.spi.JdbcSelect;
import org.hibernate.sql.exec.spi.JdbcSelectExecutor;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesMappingProducer;
import org.hibernate.sql.results.spi.ListResultsConsumer;
@ -97,14 +97,10 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
Collections.emptySet()
);
final JdbcSelectExecutor executor = JdbcSelectExecutorStandardImpl.INSTANCE;
// todo (6.0): use configurable executor instead?
// final SharedSessionContractImplementor session = executionContext.getSession();
// final SessionFactoryImplementor factory = session.getFactory();
// final JdbcServices jdbcServices = factory.getJdbcServices();
// return jdbcServices.getJdbcSelectExecutor().execute(
return executor.list(
final SharedSessionContractImplementor session = executionContext.getSession();
final SessionFactoryImplementor factory = session.getFactory();
final JdbcServices jdbcServices = factory.getJdbcServices();
return jdbcServices.getJdbcSelectExecutor().list(
jdbcSelect,
jdbcParameterBindings,
SqmJdbcExecutionContextAdapter.usingLockingAndPaging( executionContext ),
@ -146,14 +142,7 @@ public class NativeSelectQueryPlanImpl<R> implements NativeSelectQueryPlan<R> {
Collections.emptySet()
);
final JdbcSelectExecutor executor = JdbcSelectExecutorStandardImpl.INSTANCE;
// todo (6.0): use configurable executor instead?
// final SharedSessionContractImplementor session = executionContext.getSession();
// final SessionFactoryImplementor factory = session.getFactory();
// final JdbcServices jdbcServices = factory.getJdbcServices();
// return jdbcServices.getJdbcSelectExecutor().scroll(
return executor.scroll(
return executionContext.getSession().getJdbcServices().getJdbcSelectExecutor().scroll(
jdbcSelect,
scrollMode,
jdbcParameterBindings,

View File

@ -3157,9 +3157,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Expression visitQualifiedAttributeJoin(SqmAttributeJoin<?, ?> sqmJoin) {
// todo (6.0) : have this resolve to TableGroup instead?
// - trying to remove tracking of TableGroupJoin in the x-refs
final TableGroup existing = getFromClauseAccess().findTableGroup( sqmJoin.getNavigablePath() );
if ( existing != null ) {
log.tracef( "SqmAttributeJoin [%s] resolved to existing TableGroup [%s]", sqmJoin, existing );
@ -3171,9 +3168,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Expression visitCrossJoin(SqmCrossJoin<?> sqmJoin) {
// todo (6.0) : have this resolve to TableGroup instead?
// - trying to remove tracking of TableGroupJoin in the x-refs
final TableGroup existing = getFromClauseAccess().findTableGroup( sqmJoin.getNavigablePath() );
if ( existing != null ) {
log.tracef( "SqmCrossJoin [%s] resolved to existing TableGroup [%s]", sqmJoin, existing );
@ -3185,9 +3179,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Object visitPluralPartJoin(SqmPluralPartJoin<?, ?> sqmJoin) {
// todo (6.0) : have this resolve to TableGroup instead?
// - trying to remove tracking of TableGroupJoin in the x-refs
final TableGroup existing = getFromClauseAccess().findTableGroup( sqmJoin.getNavigablePath() );
if ( existing != null ) {
log.tracef( "SqmPluralPartJoin [%s] resolved to existing TableGroup [%s]", sqmJoin, existing );
@ -3199,9 +3190,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
@Override
public Expression visitQualifiedEntityJoin(SqmEntityJoin<?> sqmJoin) {
// todo (6.0) : have this resolve to TableGroup instead?
// - trying to remove tracking of TableGroupJoin in the x-refs
final TableGroup existing = getFromClauseAccess().findTableGroup( sqmJoin.getNavigablePath() );
if ( existing != null ) {
log.tracef( "SqmEntityJoin [%s] resolved to existing TableGroup [%s]", sqmJoin, existing );
@ -6750,9 +6738,6 @@ public abstract class BaseSqmToSqlAstConverter<T extends Statement> extends Base
public List<Fetch> visitFetches(FetchParent fetchParent) {
final List<Fetch> fetches = CollectionHelper.arrayList( fetchParent.getReferencedMappingType().getNumberOfFetchables() );
// todo (6.0) : determine how to best handle TREAT
// fetchParent.getReferencedMappingContainer().visitKeyFetchables( fetchableBiConsumer, treatTargetType );
// fetchParent.getReferencedMappingContainer().visitFetchables( fetchableBiConsumer, treatTargetType );
fetchParent.getReferencedMappingContainer().visitKeyFetchables( fetchable -> addFetch( fetches, fetchParent, fetchable, true ), null );
fetchParent.getReferencedMappingContainer().visitFetchables( fetchable -> addFetch( fetches, fetchParent, fetchable, false ), null );
return fetches;

View File

@ -58,6 +58,4 @@ public interface SqmTranslatorFactory {
LoadQueryInfluencers loadQueryInfluencers,
SqlAstCreationContext creationContext);
// todo (6.0) : update, delete, etc converters...
}

View File

@ -144,11 +144,6 @@ public abstract class AbstractSqmPath<T> extends AbstractSqmExpression<T> implem
@SuppressWarnings("unchecked")
public SqmPath<?> get(String attributeName) {
// todo (6.0) : this is similar to the idea of creating an SqmExpression for a Navigable
// should make these stylistically consistent, either -
// 1) add `Navigable#createCriteriaExpression` (ala, the exist `#createSqmExpression`)
// 2) remove `Navigable#createSqmExpression` and use the approach used here instead.
final SqmPathSource<?> subNavigable = getReferencedPathSource().getSubPathSource( attributeName );
return resolvePath( attributeName, subNavigable );

View File

@ -89,7 +89,6 @@ public class EntityDelayedFetchInitializer extends AbstractFetchParentAccess imp
identifier = identifierAssembler.assemble( rowProcessingState );
if ( identifier == null ) {
// todo (6.0) : check this is the correct behaviour
entityInstance = null;
}
else {

View File

@ -56,7 +56,6 @@ public class LoadingCollectionEntryImpl implements LoadingCollectionEntry {
}
@Override public Object getKey() {
// todo (6.0) : change from Serializable to Object
return key;
}

View File

@ -112,10 +112,6 @@ public class StandardRowReader<T> implements RowReader<T> {
@SuppressWarnings("ForLoopReplaceableByForEach")
private void coordinateInitializers(RowProcessingState rowProcessingState) {
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// todo (6.0) : we may want to split handling of initializers into specific sub-type handling
// - meaning we'd have something like:
final int numberOfInitializers = initializers.size();
for ( int i = 0; i < numberOfInitializers; i++ ) {

View File

@ -28,7 +28,6 @@ public abstract class AbstractResultSetAccess implements ResultSetAccess {
}
protected ResultSetMetaData getMetaData() {
// todo (6.0) : we need to consider a way to abstract this from JDBC so we can re-use all of this code for cached results as well
if ( resultSetMetaData == null ) {
try {
resultSetMetaData = getResultSet().getMetaData();

View File

@ -63,9 +63,24 @@ As discussed in <<type>> though, this change has a very big impact on Hibernate'
== Bulk SQM against entities mapped to multiple tables
// todo (6.0) - @Christian - can you add some info here?
The implementations for bulk SQM DML statements like `insert`, `update` and `delete` were significantly improved in 6.0.
An important bug fix is, that `delete` statements now properly clean up collection tables.
`insert` statements now also support inserting into multi-table entities by making use of special purpose temporary tables
into which the insert goes and is then split up into the respective tables.
There are currently 2 implementation strategies:
* Using temporary tables (the default)
* Using DML in CTEs (used on DB2 and PostgreSQL)
The temporary table approach is pretty simple and works in a similar way to how 5.x already implemented it.
Data or primary key values are first inserted into a temporary table and then the DML changes are applied to the various
tables that are affected by the SQM DML statement.
The CTE approach is new and implements a more performant approach by executing a single statement,
containing the various individual DML statements that would normally be executed separately.
This allows to run SQM DML statements in a single JDBC operation that does not move any data between the database and the application,
which should provide a significant boost for statements that involve many rows.
[[identifier-object]]
== Identifier as Object
@ -697,11 +712,8 @@ class Node {
}
```
Hibernate previously walked the graph for the `Node#node1` sub-tree prior to walking the `Node#node2` sub-tree
// todo (6.0) : clarify this some more?
being all eager we are executing a query with 4 joins
Hibernate previously generated joins by walking the entity association graph for the `Node#node1` sub-tree prior to walking the `Node#node2` sub-tree.
Since the associations are all eager, Hibernate 6.0 now executes a query with 4 joins
```
FROM Node
@ -711,14 +723,15 @@ JOIN Node.node2
JOIN Node.node2.node1
```
whereas before we
whereas before it executed
```
FROM Node
JOIN Node.node1
JOIN Node.node1.node2
```
and issue a select for `Node.node2` if the FK of `Node.node2` is not null
and issued a select for `Node.node2` if the FK of `Node.node2` was not null
```
FROM Node.node2
@ -726,8 +739,8 @@ JOIN Node.node2.node1
JOIN Node.node2.node1.node2
```
In this simple example this is not such a big deal, but if we increase the number of eager fetched self-associations
to e.g. 3 like here:
In this simple example this is not such a big deal, but if the number of eager fetched self-associations
is increased to e.g. 3 like here:
```
@Entity