From 78cf552065afd8171299ab05cbbbaf40539ff70d Mon Sep 17 00:00:00 2001 From: Andrea Boriero Date: Mon, 27 May 2024 14:50:27 +0200 Subject: [PATCH] HHH-18146 Switch to global temporary tables on H2 --- .../java/org/hibernate/dialect/H2Dialect.java | 16 +++++----------- .../temptable/LocalTemporaryTableStrategy.java | 3 --- .../unit/DialectTempTableNoCommitTest.java | 2 +- .../jpa/connection/DataSourceInjectionTest.java | 3 ++- migration-guide.adoc | 7 ++++++- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index 33e9bfbd08..ad38114ebd 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -47,9 +47,8 @@ import org.hibernate.persister.entity.mutation.EntityMutationTarget; import org.hibernate.query.sqm.FetchClauseType; import org.hibernate.query.sqm.IntervalType; import org.hibernate.query.sqm.TemporalUnit; -import org.hibernate.query.sqm.mutation.internal.temptable.BeforeUseAction; -import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableInsertStrategy; -import org.hibernate.query.sqm.mutation.internal.temptable.LocalTemporaryTableMutationStrategy; +import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableInsertStrategy; +import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableMutationStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy; import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy; import org.hibernate.service.ServiceRegistry; @@ -675,7 +674,7 @@ public class H2Dialect extends Dialect { public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy( EntityMappingType entityDescriptor, RuntimeModelCreationContext runtimeModelCreationContext) { - return new LocalTemporaryTableMutationStrategy( + return new GlobalTemporaryTableMutationStrategy( TemporaryTable.createIdTable( entityDescriptor, basename -> TemporaryTable.ID_TABLE_PREFIX + basename, @@ -690,7 +689,7 @@ public class H2Dialect extends Dialect { public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy( EntityMappingType entityDescriptor, RuntimeModelCreationContext runtimeModelCreationContext) { - return new LocalTemporaryTableInsertStrategy( + return new GlobalTemporaryTableInsertStrategy( TemporaryTable.createEntityTable( entityDescriptor, name -> TemporaryTable.ENTITY_TABLE_PREFIX + name, @@ -708,12 +707,7 @@ public class H2Dialect extends Dialect { @Override public TemporaryTableKind getSupportedTemporaryTableKind() { - return TemporaryTableKind.LOCAL; - } - - @Override - public BeforeUseAction getTemporaryTableBeforeUseAction() { - return BeforeUseAction.CREATE; + return TemporaryTableKind.GLOBAL; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/LocalTemporaryTableStrategy.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/LocalTemporaryTableStrategy.java index f276c1fa02..ba62472918 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/LocalTemporaryTableStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/mutation/internal/temptable/LocalTemporaryTableStrategy.java @@ -22,9 +22,6 @@ import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; public class LocalTemporaryTableStrategy { public static final String SHORT_NAME = "local_temporary"; - /** - * For H2 dialect avoid setting the drop strategy to true because H2 forces a commit when dropping a temporary table - */ public static final String DROP_ID_TABLES = "hibernate.query.mutation_strategy.local_temporary.drop_tables"; private final TemporaryTable temporaryTable; diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/unit/DialectTempTableNoCommitTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/unit/DialectTempTableNoCommitTest.java index c448d9e303..d10c92208a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/unit/DialectTempTableNoCommitTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/dialect/unit/DialectTempTableNoCommitTest.java @@ -57,7 +57,7 @@ public class DialectTempTableNoCommitTest { @ServiceRegistry( settings = @Setting(name = LocalTemporaryTableStrategy.DROP_ID_TABLES, value = "true") ) - @SkipForDialect(dialectClass = H2Dialect.class) +// @SkipForDialect(dialectClass = H2Dialect.class) @SessionFactory public void noCommitAfterTempTableCreationAndDropTempTableTest(SessionFactoryScope scope) { scope.inTransaction( diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/connection/DataSourceInjectionTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/connection/DataSourceInjectionTest.java index d32a70ef94..21f6a152c4 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/connection/DataSourceInjectionTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/connection/DataSourceInjectionTest.java @@ -21,6 +21,7 @@ import jakarta.persistence.PersistenceException; import javax.sql.DataSource; import org.hibernate.cfg.AvailableSettings; +import org.hibernate.dialect.DerbyDialect; import org.hibernate.dialect.H2Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; @@ -47,7 +48,7 @@ public class DataSourceInjectionTest { // otherwise the FakeDataSourceException will be eaten trying to resolve the Dialect final Map intgOverrides = Collections.singletonMap( AvailableSettings.DIALECT, - H2Dialect.class + DerbyDialect.class ); final HibernatePersistenceProvider provider = new HibernatePersistenceProvider(); diff --git a/migration-guide.adoc b/migration-guide.adoc index 36ef1a7826..7033af2b8b 100644 --- a/migration-guide.adoc +++ b/migration-guide.adoc @@ -76,4 +76,9 @@ For entities which have neither, it's impossible to distinguish a new instance f ORM 6.6 introduced support for `@Embeddable` type inheritance. With it, we also enabled the `type()` and `treat()` functions to work with embeddable-typed paths. As a consequence, the `SqmTreatedPath#getTreatTarget()` method will now return a generic `ManagedDomainType` object, -which could in turn be an `EntityDomainType` (as it was before) or also an `EmbeddableDomainType` instance. \ No newline at end of file +which could in turn be an `EntityDomainType` (as it was before) or also an `EmbeddableDomainType` instance. + +[[h2-dialect]] +== H2 database and bulk mutation strategy + +With ORM 6.6 when a bulk mutation involves multiple tables, H2 dialect will make use of global temporary tables instead of local ones. \ No newline at end of file