diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java index bdea85dbbe..7de5d1ff1f 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/DatabaseSnapshotExecutor.java @@ -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() { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdLoaderStandard.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdLoaderStandard.java index 76608d4ac2..f044608fe4 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdLoaderStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdLoaderStandard.java @@ -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 implements MultiIdEntityLoader { subSelectFetchableKeysHandler = null; } - return JdbcSelectExecutorStandardImpl.INSTANCE.list( + return session.getJdbcServices().getJdbcSelectExecutor().list( jdbcSelect, jdbcParameterBindings, new ExecutionContext() { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java index 1e3dee210c..d617b8a42b 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoadingBatcher.java @@ -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() { diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderDynamicBatch.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderDynamicBatch.java index 7379bf2e26..54ef53c25d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderDynamicBatch.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdEntityLoaderDynamicBatch.java @@ -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 extends SingleIdEntityLoaderSup jdbcParameterBindings ); - JdbcSelectExecutorStandardImpl.INSTANCE.list( + session.getJdbcServices().getJdbcSelectExecutor().list( jdbcSelect, jdbcParameterBindings, getExecutionContext( diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java index d13b22eabf..469e1ad11d 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/SingleIdLoadPlan.java @@ -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 implements SingleEntityLoadPlan { final QueryOptions queryOptions = new SimpleQueryOptions( lockOptions, readOnly ); final Callback callback = new CallbackImpl(); - final List list = JdbcSelectExecutorStandardImpl.INSTANCE.list( + final List list = session.getJdbcServices().getJdbcSelectExecutor().list( jdbcSelect, jdbcParameterBindings, new ExecutionContext() { diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java index ffc6e87e09..c12735ae45 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeNonSelectQueryPlanImpl.java @@ -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 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 diff --git a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java index 59ff1cc454..1507c9898e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sql/internal/NativeSelectQueryPlanImpl.java @@ -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 implements NativeSelectQueryPlan { 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 implements NativeSelectQueryPlan { 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, diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java index ecf91df482..43f3d98eed 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/BaseSqmToSqlAstConverter.java @@ -3157,9 +3157,6 @@ public abstract class BaseSqmToSqlAstConverter 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 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 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 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 extends Base public List visitFetches(FetchParent fetchParent) { final List 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; diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslatorFactory.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslatorFactory.java index f8ebb2dbd8..675c890e4e 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslatorFactory.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/sql/SqmTranslatorFactory.java @@ -58,6 +58,4 @@ public interface SqmTranslatorFactory { LoadQueryInfluencers loadQueryInfluencers, SqlAstCreationContext creationContext); - - // todo (6.0) : update, delete, etc converters... } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java index a90a2bf2cf..abc4177ae4 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/tree/domain/AbstractSqmPath.java @@ -144,11 +144,6 @@ public abstract class AbstractSqmPath extends AbstractSqmExpression 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 ); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java index db6d8d2f44..b5db7b8887 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/entity/internal/EntityDelayedFetchInitializer.java @@ -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 { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/LoadingCollectionEntryImpl.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/LoadingCollectionEntryImpl.java index d73a836951..443318e34c 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/LoadingCollectionEntryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/LoadingCollectionEntryImpl.java @@ -56,7 +56,6 @@ public class LoadingCollectionEntryImpl implements LoadingCollectionEntry { } @Override public Object getKey() { - // todo (6.0) : change from Serializable to Object return key; } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java index 93a22457aa..b65b4aa4a5 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/internal/StandardRowReader.java @@ -112,10 +112,6 @@ public class StandardRowReader implements RowReader { @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++ ) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/AbstractResultSetAccess.java b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/AbstractResultSetAccess.java index 67033a34e7..bb47cd7e5a 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/AbstractResultSetAccess.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/jdbc/internal/AbstractResultSetAccess.java @@ -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(); diff --git a/migration-guide.adoc b/migration-guide.adoc index d63ee709e7..609a1faa70 100644 --- a/migration-guide.adoc +++ b/migration-guide.adoc @@ -63,9 +63,24 @@ As discussed in <> 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