HHH-18854 - Changes for Hibernate Reactive 3.0 integration

This commit is contained in:
Davide D'Alto 2024-11-15 18:12:42 +01:00 committed by Steve Ebersole
parent 49886d1fd5
commit 1fe23ae2ed
14 changed files with 142 additions and 57 deletions

View File

@ -42,7 +42,6 @@
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JsonArrayJdbcType;
import static org.hibernate.dialect.StructHelper.getEmbeddedPart;
import static org.hibernate.dialect.StructHelper.instantiate;
@ -363,16 +362,17 @@ public static <X> X fromString(
return (X) values;
}
// This is also used by Hibernate Reactive
public static <X> X arrayFromString(
JavaType<X> javaType,
JsonArrayJdbcType jsonArrayJdbcType,
JdbcType elementJdbcType,
String string,
WrapperOptions options) throws SQLException {
if ( string == null ) {
return null;
}
final JavaType<?> elementJavaType = ((BasicPluralJavaType<?>) javaType).getElementJavaType();
final Class<?> preferredJavaTypeClass = jsonArrayJdbcType.getElementJdbcType().getPreferredJavaTypeClass( options );
final Class<?> preferredJavaTypeClass = elementJdbcType.getPreferredJavaTypeClass( options );
final JavaType<?> jdbcJavaType;
if ( preferredJavaTypeClass == null || preferredJavaTypeClass == elementJavaType.getJavaTypeClass() ) {
jdbcJavaType = elementJavaType;
@ -390,7 +390,7 @@ public static <X> X arrayFromString(
arrayList,
elementJavaType,
jdbcJavaType,
jsonArrayJdbcType.getElementJdbcType()
elementJdbcType
);
assert string.charAt( i - 1 ) == ']';
return javaType.wrap( arrayList, options );

View File

@ -111,6 +111,13 @@ public QualifiedName getPhysicalName() {
return physicalTableName;
}
/*
* Used by Hibernate Reactive
*/
public Identifier getLogicalValueColumnNameIdentifier() {
return logicalValueColumnNameIdentifier;
}
@Override
public int getInitialValue() {
return initialValue;

View File

@ -14,8 +14,11 @@
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.generator.Generator;
import org.hibernate.mapping.GeneratorSettings;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.tuple.entity.EntityMetamodel;
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
import org.hibernate.type.spi.TypeConfiguration;
@ -64,4 +67,11 @@ default MetadataImplementor getMetadata() {
Map<String, Generator> getGenerators();
GeneratorSettings getGeneratorSettings();
/*
* Used by Hibernate Reactive
*/
default EntityMetamodel createEntityMetamodel(PersistentClass persistentClass, EntityPersister persister) {
return new EntityMetamodel( persistentClass, persister, this );
}
}

View File

@ -500,7 +500,7 @@ public AbstractEntityPersister(
isLazyPropertiesCacheable = true;
}
entityMetamodel = new EntityMetamodel( persistentClass, this, creationContext );
entityMetamodel = creationContext.createEntityMetamodel( persistentClass, this );
entityEntryFactory = entityMetamodel.isMutable()
? MutableEntityEntryFactory.INSTANCE

View File

@ -160,7 +160,6 @@ public JoinedSubclassEntityPersister(
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
final Dialect dialect = creationContext.getDialect();

View File

@ -114,7 +114,6 @@ public SingleTableEntityPersister(
final EntityDataAccess cacheAccessStrategy,
final NaturalIdDataAccess naturalIdRegionAccessStrategy,
final RuntimeModelCreationContext creationContext) throws HibernateException {
super( persistentClass, cacheAccessStrategy, naturalIdRegionAccessStrategy, creationContext );
final Dialect dialect = creationContext.getDialect();

View File

@ -82,8 +82,7 @@ protected MutationOperationGroup createOperationGroup(ValuesAnalysis valuesAnaly
case 0:
return MutationOperationGroupFactory.noOperations( mutationGroup );
case 1: {
final MutationOperation operation = mutationGroup.getSingleTableMutation()
.createMutationOperation( valuesAnalysis, factory() );
final MutationOperation operation = createOperation( valuesAnalysis, mutationGroup.getSingleTableMutation() );
return operation == null
? MutationOperationGroupFactory.noOperations( mutationGroup )
: MutationOperationGroupFactory.singleOperation( mutationGroup, operation );
@ -116,6 +115,13 @@ protected MutationOperationGroup createOperationGroup(ValuesAnalysis valuesAnaly
}
}
/*
* Used by Hibernate Reactive
*/
protected MutationOperation createOperation(ValuesAnalysis valuesAnalysis, TableMutation<?> singleTableMutation) {
return singleTableMutation.createMutationOperation( valuesAnalysis, factory() );
}
protected void handleValueGeneration(
AttributeMapping attributeMapping,
MutationGroupBuilder mutationGroupBuilder,

View File

@ -44,7 +44,6 @@ public class DeleteOrUpsertOperation implements SelfExecutingUpdateOperation {
private final OptionalTableUpdate optionalTableUpdate;
public DeleteOrUpsertOperation(
EntityMutationTarget mutationTarget,
EntityTableMapping tableMapping,
@ -56,6 +55,16 @@ public DeleteOrUpsertOperation(
this.optionalTableUpdate = optionalTableUpdate;
}
/*
* Used by Hibernate Reactive
*/
protected DeleteOrUpsertOperation(DeleteOrUpsertOperation original) {
this.mutationTarget = original.mutationTarget;
this.tableMapping = original.tableMapping;
this.upsertOperation = original.upsertOperation;
this.optionalTableUpdate = original.optionalTableUpdate;
}
@Override
public MutationType getMutationType() {
return MutationType.UPDATE;
@ -197,4 +206,18 @@ private void performUpsert(JdbcValueBindings jdbcValueBindings, SharedSessionCon
MODEL_MUTATION_LOGGER.tracef( "`%s` rows upserted into `%s`", rowCount, tableMapping.getTableName() );
}
/*
* Used by Hibernate Reactive
*/
public UpsertOperation getUpsertOperation() {
return upsertOperation;
}
/*
* Used by Hibernate Reactive
*/
public OptionalTableUpdate getOptionalTableUpdate() {
return optionalTableUpdate;
}
}

View File

@ -263,7 +263,10 @@ private static void bindKeyValue(
}
}
private JdbcDeleteMutation createJdbcDelete(SharedSessionContractImplementor session) {
/*
* Used by Hibernate Reactive
*/
protected JdbcDeleteMutation createJdbcDelete(SharedSessionContractImplementor session) {
final TableDelete tableDelete;
if ( tableMapping.getDeleteDetails() != null
&& tableMapping.getDeleteDetails().getCustomSql() != null ) {
@ -305,39 +308,7 @@ private boolean performUpdate(
JdbcValueBindings jdbcValueBindings,
SharedSessionContractImplementor session) {
MODEL_MUTATION_LOGGER.tracef( "#performUpdate(%s)", tableMapping.getTableName() );
final TableUpdate<JdbcMutationOperation> tableUpdate;
if ( tableMapping.getUpdateDetails() != null
&& tableMapping.getUpdateDetails().getCustomSql() != null ) {
tableUpdate = new TableUpdateCustomSql(
new MutatingTableReference( tableMapping ),
mutationTarget,
"upsert update for " + mutationTarget.getRolePath(),
valueBindings,
keyBindings,
optimisticLockBindings,
parameters
);
}
else {
tableUpdate = new TableUpdateStandard(
new MutatingTableReference( tableMapping ),
mutationTarget,
"upsert update for " + mutationTarget.getRolePath(),
valueBindings,
keyBindings,
optimisticLockBindings,
parameters
);
}
final SqlAstTranslator<JdbcMutationOperation> translator = session
.getJdbcServices()
.getJdbcEnvironment()
.getSqlAstTranslatorFactory()
.buildModelMutationTranslator( tableUpdate, session.getFactory() );
final JdbcMutationOperation jdbcUpdate = translator.translate( null, MutationQueryOptions.INSTANCE );
final JdbcMutationOperation jdbcUpdate = createJdbcUpdate( session );
final PreparedStatementGroupSingleTable statementGroup = new PreparedStatementGroupSingleTable( jdbcUpdate, session );
final PreparedStatementDetails statementDetails = statementGroup.resolvePreparedStatementDetails( tableMapping.getTableName() );
@ -374,6 +345,44 @@ private boolean performUpdate(
}
}
/*
* Used by Hibernate Reactive
*/
protected JdbcMutationOperation createJdbcUpdate(SharedSessionContractImplementor session) {
final TableUpdate<JdbcMutationOperation> tableUpdate;
if ( tableMapping.getUpdateDetails() != null
&& tableMapping.getUpdateDetails().getCustomSql() != null ) {
tableUpdate = new TableUpdateCustomSql(
new MutatingTableReference( tableMapping ),
mutationTarget,
"upsert update for " + mutationTarget.getRolePath(),
valueBindings,
keyBindings,
optimisticLockBindings,
parameters
);
}
else {
tableUpdate = new TableUpdateStandard(
new MutatingTableReference( tableMapping ),
mutationTarget,
"upsert update for " + mutationTarget.getRolePath(),
valueBindings,
keyBindings,
optimisticLockBindings,
parameters
);
}
final SqlAstTranslator<JdbcMutationOperation> translator = session
.getJdbcServices()
.getJdbcEnvironment()
.getSqlAstTranslatorFactory()
.buildModelMutationTranslator( tableUpdate, session.getFactory() );
return translator.translate( null, MutationQueryOptions.INSTANCE );
}
private void performInsert(JdbcValueBindings jdbcValueBindings, SharedSessionContractImplementor session) {
final JdbcInsertMutation jdbcInsert = createJdbcInsert( session );
@ -414,7 +423,10 @@ private void performInsert(JdbcValueBindings jdbcValueBindings, SharedSessionCon
}
}
private JdbcInsertMutation createJdbcInsert(SharedSessionContractImplementor session) {
/*
* Used by Hibernate Reactive
*/
protected JdbcInsertMutation createJdbcInsert(SharedSessionContractImplementor session) {
final TableInsert tableInsert;
if ( tableMapping.getInsertDetails() != null
&& tableMapping.getInsertDetails().getCustomSql() != null ) {

View File

@ -142,11 +142,10 @@ public boolean isSelectByUniqueKey() {
public DomainResultAssembler<?> createAssembler(
InitializerParent<?> parent,
AssemblerCreationState creationState) {
final EntityInitializer<?> entityInitializer =
creationState.resolveInitializer( this, parent, this )
.asEntityInitializer();
final EntityInitializer<?> entityInitializer = creationState.resolveInitializer( this, parent, this )
.asEntityInitializer();
assert entityInitializer != null;
return new EntityAssembler<>( getFetchedMapping().getJavaType(), entityInitializer );
return buildEntityAssembler( entityInitializer );
}
@Override
@ -160,4 +159,10 @@ public EntityInitializer<?> createInitializer(
@Override
public abstract EntityInitializer<?> createInitializer(InitializerParent<?> parent, AssemblerCreationState creationState);
/**
* Used By Hibernate Reactive
*/
protected EntityAssembler<?> buildEntityAssembler(EntityInitializer<?> entityInitializer) {
return new EntityAssembler<>( getFetchedMapping().getJavaType(), entityInitializer );
}
}

View File

@ -129,9 +129,14 @@ public FetchParent getFetchParent() {
public DomainResultAssembler<?> createAssembler(
InitializerParent<?> parent,
AssemblerCreationState creationState) {
return new EntityAssembler<>( getFetchedMapping().getJavaType(),
creationState.resolveInitializer( this, parent, this )
.asEntityInitializer() );
return buildEntityAssembler( creationState.resolveInitializer( this, parent, this ).asEntityInitializer() );
}
/**
* Used by Hibernate Reactive
*/
protected EntityAssembler<?> buildEntityAssembler(EntityInitializer<?> entityInitializer) {
return new EntityAssembler<>( getFetchedMapping().getJavaType(), entityInitializer );
}
@Override

View File

@ -638,7 +638,10 @@ private void populateTablesWithColumns(
}
}
private ColumnInformationImpl columnInformation(TableInformation tableInformation, ResultSet resultSet)
/*
* Hibernate Reactive overrides this
*/
protected ColumnInformationImpl columnInformation(TableInformation tableInformation, ResultSet resultSet)
throws SQLException {
return new ColumnInformationImpl(
tableInformation,
@ -864,7 +867,10 @@ protected void addColumns(TableInformation tableInformation) {
}
}
private Boolean interpretTruthValue(String nullable) {
/*
* Used by Hibernate Reactive
*/
protected Boolean interpretTruthValue(String nullable) {
if ( "yes".equalsIgnoreCase( nullable ) ) {
return Boolean.TRUE;
}

View File

@ -13,6 +13,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
@ -149,6 +150,18 @@ public EntityMetamodel(
PersistentClass persistentClass,
EntityPersister persister,
RuntimeModelCreationContext creationContext) {
this( persistentClass, persister, creationContext,
rootName -> buildIdGenerator( rootName, persistentClass, creationContext ) );
}
/*
* Used by Hibernate Reactive to adapt the id generators
*/
public EntityMetamodel(
PersistentClass persistentClass,
EntityPersister persister,
RuntimeModelCreationContext creationContext,
Function<String, Generator> generatorSupplier) {
this.sessionFactory = creationContext.getSessionFactory();
// Improves performance of EntityKey#equals by avoiding content check in String#equals
@ -160,7 +173,7 @@ public EntityMetamodel(
subclassId = persistentClass.getSubclassId();
final Generator idgenerator = buildIdGenerator( persistentClass, creationContext );
final Generator idgenerator = generatorSupplier.apply( rootName );
identifierAttribute = PropertyFactory.buildIdentifierAttribute( persistentClass, idgenerator );
versioned = persistentClass.isVersioned();
@ -483,7 +496,7 @@ private static boolean writePropertyValue(OnExecutionGenerator generator) {
return writePropertyValue;
}
private Generator buildIdGenerator(PersistentClass persistentClass, RuntimeModelCreationContext creationContext) {
private static Generator buildIdGenerator(String rootName, PersistentClass persistentClass, RuntimeModelCreationContext creationContext) {
final Generator existing = creationContext.getGenerators().get( rootName );
if ( existing != null ) {
return existing;

View File

@ -59,7 +59,7 @@ protected <X> X fromString(String string, JavaType<X> javaType, WrapperOptions o
if ( string == null ) {
return null;
}
return JsonHelper.arrayFromString( javaType, this, string, options );
return JsonHelper.arrayFromString( javaType, this.getElementJdbcType(), string, options );
}
protected <X> String toString(X value, JavaType<X> javaType, WrapperOptions options) {