Skip to content

Commit

Permalink
HHH-18854 - Changes for Hibernate Reactive 3.0 integration
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideD authored and sebersole committed Nov 27, 2024
1 parent 49886d1 commit 1fe23ae
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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 );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ public QualifiedName getPhysicalName() {
return physicalTableName;
}

/*
* Used by Hibernate Reactive
*/
public Identifier getLogicalValueColumnNameIdentifier() {
return logicalValueColumnNameIdentifier;
}

@Override
public int getInitialValue() {
return initialValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ public AbstractEntityPersister(
isLazyPropertiesCacheable = true;
}

entityMetamodel = new EntityMetamodel( persistentClass, this, creationContext );
entityMetamodel = creationContext.createEntityMetamodel( persistentClass, this );

entityEntryFactory = entityMetamodel.isMutable()
? MutableEntityEntryFactory.INSTANCE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ public class DeleteOrUpsertOperation implements SelfExecutingUpdateOperation {

private final OptionalTableUpdate optionalTableUpdate;


public DeleteOrUpsertOperation(
EntityMutationTarget mutationTarget,
EntityTableMapping tableMapping,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down Expand Up @@ -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() );
Expand Down Expand Up @@ -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 );

Expand Down Expand Up @@ -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 ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit 1fe23ae

Please sign in to comment.