Skip to content

HHH-18311 Allow constructing SqmMultiTableInsertStrategy/SqmMultiTableMutationStrategy with EntityDomainType and MappingModelCreationProcess #10609

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

import jakarta.persistence.TemporalType;
import jakarta.persistence.Timeout;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.hibernate.Timeouts;
import org.hibernate.boot.model.FunctionContributions;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.community.dialect.sequence.LegacyDB2SequenceSupport;
import org.hibernate.community.dialect.temptable.DB2LegacyLocalTemporaryTableStrategy;
import org.hibernate.dialect.DB2GetObjectExtractor;
import org.hibernate.dialect.DatabaseVersion;
import org.hibernate.dialect.Dialect;
Expand All @@ -33,6 +35,8 @@
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.sequence.DB2SequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.temptable.DB2GlobalTemporaryTableStrategy;
import org.hibernate.dialect.temptable.TemporaryTableStrategy;
import org.hibernate.dialect.type.DB2StructJdbcType;
import org.hibernate.dialect.unique.AlterTableUniqueIndexDelegate;
import org.hibernate.dialect.unique.SkipNullableUniqueDelegate;
Expand Down Expand Up @@ -1041,6 +1045,21 @@ public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
return new CteInsertStrategy( rootEntityDescriptor, runtimeModelCreationContext );
}

@Override
public @Nullable TemporaryTableStrategy getGlobalTemporaryTableStrategy() {
// Starting in DB2 9.7, "real" global temporary tables that can be shared between sessions
// are supported; (obviously) data is not shared between sessions.
return getDB2Version().isBefore( 9, 7 ) ? null : DB2GlobalTemporaryTableStrategy.INSTANCE;
}

@Override
public @Nullable TemporaryTableStrategy getLocalTemporaryTableStrategy() {
// Prior to DB2 9.7, "real" global temporary tables that can be shared between sessions
// are *not* supported; even though the DB2 command says to declare a "global" temp table
// Hibernate treats it as a "local" temp table.
return getDB2Version().isBefore( 9, 7 ) ? DB2LegacyLocalTemporaryTableStrategy.INSTANCE : null;
}

@Override
public boolean supportsCurrentTimestampSelection() {
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@
import org.hibernate.dialect.lock.spi.LockingSupport;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.temptable.TemporaryTable;
import org.hibernate.community.dialect.temptable.DerbyLocalTemporaryTableStrategy;
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.dialect.temptable.TemporaryTableStrategy;
import org.hibernate.dialect.unique.CreateTableUniqueDelegate;
import org.hibernate.dialect.unique.UniqueDelegate;
import org.hibernate.engine.jdbc.Size;
Expand All @@ -52,10 +53,9 @@
import org.hibernate.query.common.TemporalUnit;
import org.hibernate.query.sqm.CastType;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableMutationStrategy;
import org.hibernate.query.sqm.mutation.spi.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.spi.BeforeUseAction;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.service.ServiceRegistry;
Expand Down Expand Up @@ -975,46 +975,18 @@ protected void registerDefaultKeywords() {
registerKeyword( "YEAR" );
}

/**
* {@inheritDoc}
* <p>
* From Derby docs:
* <pre>
* The DECLARE GLOBAL TEMPORARY TABLE statement defines a temporary table for the current connection.
* </pre>
* <p>
* {@link DB2Dialect} returns a {@link GlobalTemporaryTableMutationStrategy} that
* will make temporary tables created at startup and hence unavailable for subsequent connections.<br/>
* see HHH-10238.
*/
@Override
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
EntityMappingType rootEntityDescriptor,
RuntimeModelCreationContext runtimeModelCreationContext) {
return new LocalTemporaryTableMutationStrategy(
TemporaryTable.createIdTable(
rootEntityDescriptor,
basename -> "session." + TemporaryTable.ID_TABLE_PREFIX + basename,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
return new LocalTemporaryTableMutationStrategy( rootEntityDescriptor, runtimeModelCreationContext );
}

@Override
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
EntityMappingType rootEntityDescriptor,
RuntimeModelCreationContext runtimeModelCreationContext) {
return new LocalTemporaryTableInsertStrategy(
TemporaryTable.createEntityTable(
rootEntityDescriptor,
name -> "session." + TemporaryTable.ENTITY_TABLE_PREFIX + name,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
return new LocalTemporaryTableInsertStrategy( rootEntityDescriptor, runtimeModelCreationContext );
}

@Override
Expand All @@ -1023,23 +995,28 @@ public TemporaryTableKind getSupportedTemporaryTableKind() {
}

@Override
public String getTemporaryTableCreateOptions() {
return "not logged";
public TemporaryTableStrategy getLocalTemporaryTableStrategy() {
return DerbyLocalTemporaryTableStrategy.INSTANCE;
}

@Override
public boolean supportsTemporaryTablePrimaryKey() {
return false;
public String getTemporaryTableCreateOptions() {
return DerbyLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableCreateOptions();
}

@Override
public String getTemporaryTableCreateCommand() {
return "declare global temporary table";
return DerbyLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableCreateCommand();
}

@Override
public BeforeUseAction getTemporaryTableBeforeUseAction() {
return BeforeUseAction.CREATE;
return DerbyLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableBeforeUseAction();
}

@Override
public boolean supportsTemporaryTablePrimaryKey() {
return DerbyLocalTemporaryTableStrategy.INSTANCE.supportsTemporaryTablePrimaryKey();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@
import org.hibernate.dialect.pagination.AbstractLimitHandler;
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.temptable.TemporaryTable;
import org.hibernate.community.dialect.temptable.DerbyLocalTemporaryTableStrategy;
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.dialect.temptable.TemporaryTableStrategy;
import org.hibernate.engine.jdbc.Size;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
Expand All @@ -51,10 +52,9 @@
import org.hibernate.query.common.TemporalUnit;
import org.hibernate.query.sqm.CastType;
import org.hibernate.query.sqm.IntervalType;
import org.hibernate.query.sqm.mutation.internal.temptable.GlobalTemporaryTableMutationStrategy;
import org.hibernate.query.sqm.mutation.spi.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.spi.BeforeUseAction;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableInsertStrategy;
import org.hibernate.query.sqm.mutation.spi.SqmMultiTableMutationStrategy;
import org.hibernate.service.ServiceRegistry;
Expand Down Expand Up @@ -978,46 +978,18 @@ protected void registerDefaultKeywords() {
registerKeyword( "YEAR" );
}

/**
* {@inheritDoc}
* <p>
* From Derby docs:
* <pre>
* The DECLARE GLOBAL TEMPORARY TABLE statement defines a temporary table for the current connection.
* </pre>
*
* {@link DB2Dialect} returns a {@link GlobalTemporaryTableMutationStrategy} that
* will make temporary tables created at startup and hence unavailable for subsequent connections.<br/>
* see HHH-10238.
*/
@Override
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
EntityMappingType rootEntityDescriptor,
RuntimeModelCreationContext runtimeModelCreationContext) {
return new LocalTemporaryTableMutationStrategy(
TemporaryTable.createIdTable(
rootEntityDescriptor,
basename -> "session." + TemporaryTable.ID_TABLE_PREFIX + basename,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
return new LocalTemporaryTableMutationStrategy( rootEntityDescriptor, runtimeModelCreationContext );
}

@Override
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
EntityMappingType rootEntityDescriptor,
RuntimeModelCreationContext runtimeModelCreationContext) {
return new LocalTemporaryTableInsertStrategy(
TemporaryTable.createEntityTable(
rootEntityDescriptor,
name -> "session." + TemporaryTable.ENTITY_TABLE_PREFIX + name,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
return new LocalTemporaryTableInsertStrategy( rootEntityDescriptor, runtimeModelCreationContext );
}

@Override
Expand All @@ -1026,23 +998,28 @@ public TemporaryTableKind getSupportedTemporaryTableKind() {
}

@Override
public String getTemporaryTableCreateOptions() {
return "not logged";
public TemporaryTableStrategy getLocalTemporaryTableStrategy() {
return DerbyLocalTemporaryTableStrategy.INSTANCE;
}

@Override
public boolean supportsTemporaryTablePrimaryKey() {
return false;
public String getTemporaryTableCreateOptions() {
return DerbyLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableCreateOptions();
}

@Override
public String getTemporaryTableCreateCommand() {
return "declare global temporary table";
return DerbyLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableCreateCommand();
}

@Override
public BeforeUseAction getTemporaryTableBeforeUseAction() {
return BeforeUseAction.CREATE;
return DerbyLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableBeforeUseAction();
}

@Override
public boolean supportsTemporaryTablePrimaryKey() {
return DerbyLocalTemporaryTableStrategy.INSTANCE.supportsTemporaryTablePrimaryKey();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@
import org.hibernate.dialect.pagination.LimitHandler;
import org.hibernate.dialect.pagination.OffsetFetchLimitHandler;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.temptable.TemporaryTable;
import org.hibernate.dialect.temptable.StandardGlobalTemporaryTableStrategy;
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.dialect.temptable.TemporaryTableStrategy;
import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder;
Expand Down Expand Up @@ -1023,40 +1024,29 @@ public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(EntityMappingType entityDescriptor, RuntimeModelCreationContext runtimeModelCreationContext) {
return getVersion().isBefore( 2,1 )
? super.getFallbackSqmMutationStrategy( entityDescriptor, runtimeModelCreationContext )
: new GlobalTemporaryTableMutationStrategy(
TemporaryTable.createIdTable(
entityDescriptor,
name -> TemporaryTable.ID_TABLE_PREFIX + name,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
: new GlobalTemporaryTableMutationStrategy( entityDescriptor, runtimeModelCreationContext );
}

@Override
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(EntityMappingType entityDescriptor, RuntimeModelCreationContext runtimeModelCreationContext) {
return getVersion().isBefore( 2, 1 )
? super.getFallbackSqmInsertStrategy( entityDescriptor, runtimeModelCreationContext )
: new GlobalTemporaryTableInsertStrategy(
TemporaryTable.createEntityTable(
entityDescriptor,
name -> TemporaryTable.ENTITY_TABLE_PREFIX + name,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
: new GlobalTemporaryTableInsertStrategy( entityDescriptor, runtimeModelCreationContext );
}

@Override
public TemporaryTableKind getSupportedTemporaryTableKind() {
return TemporaryTableKind.GLOBAL;
}

@Override
public TemporaryTableStrategy getGlobalTemporaryTableStrategy() {
return StandardGlobalTemporaryTableStrategy.INSTANCE;
}

@Override
public String getTemporaryTableCreateOptions() {
return "on commit delete rows";
return StandardGlobalTemporaryTableStrategy.INSTANCE.getTemporaryTableCreateOptions();
}

private final FirebirdIndexExporter indexExporter = new FirebirdIndexExporter( this );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@
import org.hibernate.dialect.sequence.H2V1SequenceSupport;
import org.hibernate.dialect.sequence.H2V2SequenceSupport;
import org.hibernate.dialect.sequence.SequenceSupport;
import org.hibernate.dialect.temptable.TemporaryTable;
import org.hibernate.dialect.temptable.StandardLocalTemporaryTableStrategy;
import org.hibernate.dialect.temptable.TemporaryTableKind;
import org.hibernate.dialect.temptable.TemporaryTableStrategy;
import org.hibernate.dialect.type.H2DurationIntervalSecondJdbcType;
import org.hibernate.dialect.type.H2JsonArrayJdbcTypeConstructor;
import org.hibernate.dialect.type.H2JsonJdbcType;
Expand Down Expand Up @@ -787,40 +788,29 @@ public NullOrdering getNullOrdering() {
public SqmMultiTableMutationStrategy getFallbackSqmMutationStrategy(
EntityMappingType entityDescriptor,
RuntimeModelCreationContext runtimeModelCreationContext) {
return new LocalTemporaryTableMutationStrategy(
TemporaryTable.createIdTable(
entityDescriptor,
basename -> TemporaryTable.ID_TABLE_PREFIX + basename,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
return new LocalTemporaryTableMutationStrategy( entityDescriptor, runtimeModelCreationContext );
}

@Override
public SqmMultiTableInsertStrategy getFallbackSqmInsertStrategy(
EntityMappingType entityDescriptor,
RuntimeModelCreationContext runtimeModelCreationContext) {
return new LocalTemporaryTableInsertStrategy(
TemporaryTable.createEntityTable(
entityDescriptor,
name -> TemporaryTable.ENTITY_TABLE_PREFIX + name,
this,
runtimeModelCreationContext
),
runtimeModelCreationContext.getSessionFactory()
);
return new LocalTemporaryTableInsertStrategy( entityDescriptor, runtimeModelCreationContext );
}

@Override
public TemporaryTableKind getSupportedTemporaryTableKind() {
return TemporaryTableKind.LOCAL;
}

@Override
public TemporaryTableStrategy getLocalTemporaryTableStrategy() {
return StandardLocalTemporaryTableStrategy.INSTANCE;
}

@Override
public BeforeUseAction getTemporaryTableBeforeUseAction() {
return BeforeUseAction.CREATE;
return StandardLocalTemporaryTableStrategy.INSTANCE.getTemporaryTableBeforeUseAction();
}

@Override
Expand Down
Loading