Skip to content

Commit d5764a2

Browse files
committed
cleanups to id generation stuff
1 parent 0154d64 commit d5764a2

File tree

7 files changed

+71
-116
lines changed

7 files changed

+71
-116
lines changed

hibernate-reactive-core/src/main/java/org/hibernate/reactive/event/impl/AbstractReactiveSaveEventListener.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import static org.hibernate.generator.EventType.INSERT;
4949
import static org.hibernate.id.IdentifierGeneratorHelper.SHORT_CIRCUIT_INDICATOR;
5050
import static org.hibernate.pretty.MessageHelper.infoString;
51+
import static org.hibernate.reactive.id.impl.IdentifierGeneration.castToIdentifierType;
5152
import static org.hibernate.reactive.util.impl.CompletionStages.completedFuture;
5253
import static org.hibernate.reactive.util.impl.CompletionStages.failedFuture;
5354
import static org.hibernate.reactive.util.impl.CompletionStages.nullFuture;
@@ -131,11 +132,13 @@ protected CompletionStage<Void> reactiveSaveWithGeneratedId(
131132
if ( generator instanceof ReactiveIdentifierGenerator ) {
132133
return ( (ReactiveIdentifierGenerator<?>) generator )
133134
.generate( ( ReactiveConnectionSupplier ) source, entity )
135+
.thenApply( id -> castToIdentifierType( id, persister ) )
134136
.thenCompose( generatedId -> performSaveWithId( entity, context, source, persister, generator, generatedId ) );
135137
}
136138

137139
final Object generatedId = ( (BeforeExecutionGenerator) generator ).generate( source, entity, null, INSERT );
138-
return performSaveWithId( entity, context, source, persister, generator, generatedId );
140+
final Object id = castToIdentifierType( generatedId, persister );
141+
return performSaveWithId( entity, context, source, persister, generator, id );
139142
}
140143
else {
141144
return reactivePerformSave( entity, null, persister, true, context, source, requiresImmediateIdAccess );

hibernate-reactive-core/src/main/java/org/hibernate/reactive/id/impl/IdentifierGeneration.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,19 @@ private static Object castLongIdToIdentifierType(Long longId, EntityPersister pe
4949
return longId.toString();
5050
}
5151

52-
throw LOG.cannotGenerateIdentifiersOfType( identifierType.getJavaType().getTypeName(), persister.getEntityName() );
52+
throw LOG.cannotGenerateIdentifiersOfType(
53+
identifierType.getJavaType().getTypeName(),
54+
persister.getEntityName()
55+
);
5356
}
5457

5558
private static void validateMaxValue(EntityPersister persister, Long id, int maxValue) {
5659
if ( id > maxValue ) {
57-
throw LOG.generatedIdentifierTooBigForTheField(persister.getEntityName(), persister.getIdentifierType().getReturnedClass().getSimpleName(), id );
60+
throw LOG.generatedIdentifierTooBigForTheField(
61+
persister.getEntityName(),
62+
persister.getIdentifierType().getReturnedClass().getSimpleName(),
63+
id
64+
);
5865
}
5966
}
6067
}

hibernate-reactive-core/src/main/java/org/hibernate/reactive/id/impl/ReactiveGeneratorWrapper.java

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,73 +10,43 @@
1010
import org.hibernate.boot.model.relational.SqlStringGenerationContext;
1111
import org.hibernate.engine.spi.SharedSessionContractImplementor;
1212
import org.hibernate.id.IdentifierGenerator;
13-
import org.hibernate.id.enhanced.DatabaseStructure;
14-
import org.hibernate.id.enhanced.SequenceStyleGenerator;
1513
import org.hibernate.reactive.id.ReactiveIdentifierGenerator;
16-
import org.hibernate.reactive.logging.impl.Log;
17-
import org.hibernate.reactive.logging.impl.LoggerFactory;
1814
import org.hibernate.reactive.session.ReactiveConnectionSupplier;
1915

20-
import java.lang.invoke.MethodHandles;
2116
import java.util.Objects;
2217
import java.util.concurrent.CompletionStage;
2318

2419
/**
2520
* @author Gavin King
2621
*/
27-
public class ReactiveGeneratorWrapper<T>
28-
implements IdentifierGenerator, ExportableProducer, ReactiveIdentifierGenerator<T> {
22+
public class ReactiveGeneratorWrapper
23+
implements IdentifierGenerator, ExportableProducer, ReactiveIdentifierGenerator<Object> {
2924

30-
private static final Log LOG = LoggerFactory.make( Log.class, MethodHandles.lookup() );
25+
private final ReactiveIdentifierGenerator<?> reactiveGenerator;
26+
private final IdentifierGenerator generator;
3127

32-
private final DatabaseStructure databaseStructure;
33-
private ReactiveIdentifierGenerator<T> reactiveGenerator;
34-
private IdentifierGenerator generator;
35-
private Class<T> returnedClass;
36-
37-
public ReactiveGeneratorWrapper(ReactiveIdentifierGenerator<T> reactiveGenerator, Class<T> returnedClass) {
38-
this( reactiveGenerator, null, returnedClass );
28+
public ReactiveGeneratorWrapper(ReactiveIdentifierGenerator<?> reactiveGenerator) {
29+
this( reactiveGenerator, null );
3930
}
4031

41-
public ReactiveGeneratorWrapper(ReactiveIdentifierGenerator<T> reactiveGenerator, IdentifierGenerator generator, Class<T> returnedClass) {
32+
public ReactiveGeneratorWrapper(ReactiveIdentifierGenerator<?> reactiveGenerator, IdentifierGenerator generator) {
4233
this.reactiveGenerator = reactiveGenerator;
4334
this.generator = generator;
44-
this.returnedClass = returnedClass;
45-
this.databaseStructure = generator instanceof SequenceStyleGenerator
46-
? ( (SequenceStyleGenerator) generator ).getDatabaseStructure()
47-
: null;
4835
}
4936

5037
@Override
5138
public void initialize(SqlStringGenerationContext context) {
5239
if ( reactiveGenerator instanceof IdentifierGenerator ) {
5340
( (IdentifierGenerator) reactiveGenerator ).initialize( context );
5441
}
55-
if (generator != null) {
42+
if ( generator != null ) {
5643
generator.initialize( context );
5744
}
5845
}
5946

6047
@Override
61-
public CompletionStage<T> generate(ReactiveConnectionSupplier session, Object entity) {
62-
return reactiveGenerator
63-
.generate( session, entity )
64-
.thenApply( id -> {
65-
//FIXME: this is just a temp workaround
66-
// The correct approach would be to use an IntegralDataTypeHolder
67-
if ( Integer.class.equals( returnedClass ) ) {
68-
return ( (Number) id ).intValue();
69-
}
70-
if ( Short.class.equals( returnedClass ) ) {
71-
return ( (Number) id ).shortValue();
72-
}
73-
return id;
74-
} )
75-
.thenApply( this::castId );
76-
}
77-
78-
private T castId(Object id) {
79-
return (T) id;
48+
public CompletionStage<Object> generate(ReactiveConnectionSupplier session, Object entity) {
49+
return reactiveGenerator.generate( session, entity ).thenApply( id -> id );
8050
}
8151

8252
@Override

hibernate-reactive-core/src/main/java/org/hibernate/reactive/id/impl/ReactiveIdentifierGeneratorFactory.java

Lines changed: 31 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -48,72 +48,54 @@ public ReactiveIdentifierGeneratorFactory(ServiceRegistry serviceRegistry) {
4848
public Generator createIdentifierGenerator(String strategy, Type type, Properties config) {
4949
Object generator;
5050
try {
51-
generator = super.createIdentifierGenerator(strategy, type, config);
52-
} catch (MappingException ignored) {
53-
generator = fallbackCreateIdentifierGenerator( strategy, type, config );
51+
generator = super.createIdentifierGenerator( strategy, type, config );
52+
}
53+
catch ( MappingException ignored ) {
54+
try {
55+
final Class<?> clazz = generatorClassForName( strategy );
56+
generator = clazz.getConstructor().newInstance();
57+
if ( generator instanceof Configurable ) {
58+
( (Configurable) generator ).configure( type, config, serviceRegistry );
59+
}
60+
}
61+
catch ( Exception e ) {
62+
final String entityName = config.getProperty( IdentifierGenerator.ENTITY_NAME );
63+
throw new MappingException( String.format( "Could not instantiate id generator [entity-name=%s]", entityName ), e );
64+
}
5465
}
5566

5667
//FIXME: Not sure why we need all these instanceof
5768
if ( generator instanceof BeforeExecutionGenerator ) {
58-
return augmentWithReactiveGenerator( (BeforeExecutionGenerator)generator, type, config );
69+
return augmentWithReactiveGenerator( (BeforeExecutionGenerator) generator, type, config );
5970
}
6071

6172
if ( generator instanceof OnExecutionGenerator ) {
62-
return augmentWithReactiveGenerator( (OnExecutionGenerator)generator, type, config );
73+
return augmentWithReactiveGenerator( (OnExecutionGenerator) generator, type, config );
6374
}
6475

6576
if ( generator instanceof ReactiveIdentifierGenerator ) {
66-
return new ReactiveGeneratorWrapper( (ReactiveIdentifierGenerator) generator, type.getReturnedClass() );
77+
return new ReactiveGeneratorWrapper( (ReactiveIdentifierGenerator<?>) generator );
6778
}
6879

6980
final String entityName = config.getProperty( IdentifierGenerator.ENTITY_NAME );
7081
throw new MappingException( String.format( "Not an id generator [entity-name=%s]", entityName ) );
7182
}
7283

73-
//TODO this was copied from StandardIdentifierGeneratorFactory#createIdentifierGenerator
74-
// in order to avoid the !Generator.class.isAssignableFrom( clazz ) check in getIdentifierGeneratorClass
75-
// This is suboptimal not only because we are duplicating code, but because this piece cannot access
76-
// the private fields of the super method
77-
private Object fallbackCreateIdentifierGenerator(String strategy, Type type, Properties parameters) {
78-
try {
79-
final Class<?> clazz = fallbackGetIdentifierGeneratorClass( strategy );
80-
Object result = clazz.getConstructor().newInstance();
81-
82-
if ( result instanceof Configurable ) {
83-
( (Configurable) result ).configure( type, parameters, serviceRegistry );
84-
}
85-
return result;
86-
}
87-
catch ( Exception e ) {
88-
final String entityName = parameters.getProperty( IdentifierGenerator.ENTITY_NAME );
89-
throw new MappingException( String.format( "Could not instantiate id generator [entity-name=%s]", entityName ), e );
90-
}
91-
}
92-
84+
//TODO: deleteme, after update to ORM
9385
@Override
9486
public Class<? extends Generator> getIdentifierGeneratorClass(String strategy) {
9587
try {
96-
return super.getIdentifierGeneratorClass(strategy);
97-
} catch (MappingException ignored) {
98-
return fallbackGetIdentifierGeneratorClass(strategy);
88+
return super.getIdentifierGeneratorClass( strategy );
9989
}
100-
}
101-
102-
//TODO this was copied from StandardIdentifierGeneratorFactory#createIdentifierGenerator
103-
// in order to avoid the !Generator.class.isAssignableFrom( clazz ) check in getIdentifierGeneratorClass
104-
// This is suboptimal not only because we are duplicating code, but because this piece cannot access
105-
// the private fields of the super method
106-
public Class<? extends Generator> fallbackGetIdentifierGeneratorClass(String strategy) {
107-
if ( "hilo".equals( strategy ) ) {
108-
throw new UnsupportedOperationException( "Support for 'hilo' generator has been removed" );
90+
catch ( MappingException ignored ) {
91+
// happens because the class does not implement Generator
92+
return generatorClassForName( strategy );
10993
}
110-
final String resolvedStrategy = "native".equals( strategy )
111-
? getDialect().getNativeIdentifierGeneratorStrategy()
112-
: strategy;
94+
}
11395

96+
protected Class<? extends Generator> generatorClassForName(String strategy) {
11497
try {
115-
return serviceRegistry.getService( ClassLoaderService.class )
116-
.classForName( resolvedStrategy );
98+
return serviceRegistry.getService( ClassLoaderService.class ).classForName( strategy );
11799
}
118100
catch ( ClassLoadingException e ) {
119101
throw new MappingException( String.format( "Could not interpret id generator strategy [%s]", strategy ) );
@@ -125,9 +107,9 @@ public Generator augmentWithReactiveGenerator(Generator generator, Type type, Pr
125107
}
126108

127109
public static Generator augmentWithReactiveGenerator(ServiceRegistry serviceRegistry, Generator generator, Type type, Properties params) {
128-
ReactiveIdentifierGenerator<?> reactiveGenerator;
110+
final ReactiveIdentifierGenerator<?> reactiveGenerator;
129111
if ( generator instanceof SequenceStyleGenerator ) {
130-
DatabaseStructure structure = ( (SequenceStyleGenerator) generator ).getDatabaseStructure();
112+
final DatabaseStructure structure = ( (SequenceStyleGenerator) generator ).getDatabaseStructure();
131113
if ( structure instanceof TableStructure ) {
132114
reactiveGenerator = new EmulatedSequenceReactiveIdentifierGenerator();
133115
}
@@ -151,22 +133,22 @@ else if ( generator instanceof SelectGenerator ) {
151133

152134
//this is not the way ORM does this: instead it passes a
153135
//SqlStringGenerationContext to IdentifierGenerator.initialize()
154-
ConfigurationService cs = serviceRegistry.getService( ConfigurationService.class );
136+
final ConfigurationService cs = serviceRegistry.getService( ConfigurationService.class );
155137
if ( !params.containsKey( PersistentIdentifierGenerator.SCHEMA ) ) {
156-
String schema = cs.getSetting( Settings.DEFAULT_SCHEMA, StandardConverters.STRING );
138+
final String schema = cs.getSetting( Settings.DEFAULT_SCHEMA, StandardConverters.STRING );
157139
if ( schema != null ) {
158140
params.put( PersistentIdentifierGenerator.SCHEMA, schema );
159141
}
160142
}
161143
if ( !params.containsKey( PersistentIdentifierGenerator.CATALOG ) ) {
162-
String catalog = cs.getSetting( Settings.DEFAULT_CATALOG, StandardConverters.STRING );
144+
final String catalog = cs.getSetting( Settings.DEFAULT_CATALOG, StandardConverters.STRING );
163145
if ( catalog != null ) {
164146
params.put( PersistentIdentifierGenerator.CATALOG, catalog );
165147
}
166148
}
167149

168150
( (Configurable) reactiveGenerator ).configure( type, params, serviceRegistry );
169-
return new ReactiveGeneratorWrapper( reactiveGenerator, (IdentifierGenerator) generator, type.getReturnedClass() );
151+
return new ReactiveGeneratorWrapper( reactiveGenerator, (IdentifierGenerator) generator );
170152
}
171153

172154
}

hibernate-reactive-core/src/main/java/org/hibernate/reactive/persister/entity/mutation/ReactiveInsertCoordinator.java

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import org.hibernate.generator.BeforeExecutionGenerator;
1919
import org.hibernate.generator.Generator;
2020
import org.hibernate.metamodel.mapping.AttributeMapping;
21-
import org.hibernate.metamodel.mapping.AttributeMappingsList;
2221
import org.hibernate.persister.entity.AbstractEntityPersister;
2322
import org.hibernate.persister.entity.mutation.EntityTableMapping;
2423
import org.hibernate.persister.entity.mutation.InsertCoordinator;
@@ -47,7 +46,7 @@ public Object coordinateInsert(Object id, Object[] values, Object entity, Shared
4746
}
4847

4948
public CompletionStage<Object> coordinateReactiveInsert(Object id, Object[] currentValues, Object entity, SharedSessionContractImplementor session) {
50-
return reactivePreInsertInMemoryValueGeneration(currentValues, entity, session)
49+
return reactivePreInsertInMemoryValueGeneration( currentValues, entity, session )
5150
.thenCompose( v -> entityPersister().getEntityMetamodel().isDynamicInsert()
5251
? doDynamicInserts( id, currentValues, entity, session )
5352
: doStaticInserts( id, currentValues, entity, session )
@@ -67,8 +66,8 @@ private CompletionStage<Void> reactivePreInsertInMemoryValueGeneration(Object[]
6766
&& !generator.generatedOnExecution()
6867
&& generator.generatesOnInsert() ) {
6968
final Object currentValue = currentValues[i];
70-
stage = stage.thenCompose( v -> generateValue( session, entity, currentValue,
71-
(BeforeExecutionGenerator) generator, INSERT)
69+
final BeforeExecutionGenerator beforeGenerator = (BeforeExecutionGenerator) generator;
70+
stage = stage.thenCompose( v -> generateValue( session, entity, currentValue, beforeGenerator, INSERT )
7271
.thenAccept( generatedValue -> {
7372
currentValues[index] = generatedValue;
7473
entityPersister().setPropertyValue( entity, index, generatedValue );
@@ -101,7 +100,6 @@ protected CompletionStage<Void> decomposeForReactiveInsert(
101100
TableInclusionChecker tableInclusionChecker,
102101
SharedSessionContractImplementor session) {
103102
final JdbcValueBindings jdbcValueBindings = mutationExecutor.getJdbcValueBindings();
104-
final AttributeMappingsList attributeMappings = entityPersister().getAttributeMappings();
105103
mutationGroup.forEachOperation( (position, operation) -> {
106104
final EntityTableMapping tableDetails = (EntityTableMapping) operation.getTableDetails();
107105
if ( tableInclusionChecker.include( tableDetails ) ) {
@@ -181,9 +179,6 @@ private ReactiveMutationExecutor getReactiveMutationExecutor(SharedSessionContra
181179
.getFactory()
182180
.getServiceRegistry()
183181
.getService( MutationExecutorService.class );
184-
185-
MutationExecutor executor = mutationExecutorService
186-
.createExecutor( this::getInsertBatchKey, operationGroup, session );
187-
return (ReactiveMutationExecutor) executor;
182+
return (ReactiveMutationExecutor) mutationExecutorService.createExecutor( this::getInsertBatchKey, operationGroup, session );
188183
}
189184
}

hibernate-reactive-core/src/main/java/org/hibernate/reactive/persister/entity/mutation/ReactiveUpdateCoordinatorStandard.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ public CompletionStage<Void> coordinateReactiveUpdate(
8989
}
9090

9191
CompletionStage<Void> s = voidFuture();
92-
return s.thenCompose(v -> reactivePreUpdateInMemoryValueGeneration(entity, values, session))
93-
.thenCompose(preUpdateGeneratedAttributeIndexes -> {
92+
return s.thenCompose( v -> reactivePreUpdateInMemoryValueGeneration(entity, values, session) )
93+
.thenCompose( preUpdateGeneratedAttributeIndexes -> {
9494
final int[] dirtyAttributeIndexes = dirtyAttributeIndexes( incomingDirtyAttributeIndexes, preUpdateGeneratedAttributeIndexes );
9595

9696
final boolean[] attributeUpdateability;
@@ -172,8 +172,8 @@ private CompletionStage<int[]> reactivePreUpdateInMemoryValueGeneration(
172172
&& !generator.generatedOnExecution()
173173
&& generator.generatesOnUpdate() ) {
174174
final Object currentValue = currentValues[i];
175-
result = result.thenCompose( v -> generateValue( session, entity, currentValue,
176-
(BeforeExecutionGenerator) generator, INSERT)
175+
final BeforeExecutionGenerator beforeGenerator = (BeforeExecutionGenerator) generator;
176+
result = result.thenCompose( v -> generateValue( session, entity, currentValue, beforeGenerator, INSERT )
177177
.thenAccept( generatedValue -> {
178178
currentValues[index] = generatedValue;
179179
entityPersister().setPropertyValue( entity, index, generatedValue );
@@ -261,9 +261,7 @@ private ReactiveMutationExecutor mutationExecutor(
261261
final MutationExecutorService mutationExecutorService = session.getSessionFactory()
262262
.getServiceRegistry()
263263
.getService( MutationExecutorService.class );
264-
265-
return (ReactiveMutationExecutor) mutationExecutorService
266-
.createExecutor( this::getBatchKey, operationGroup, session );
264+
return (ReactiveMutationExecutor) mutationExecutorService.createExecutor( this::getBatchKey, operationGroup, session );
267265
}
268266

269267
@Override
@@ -286,11 +284,6 @@ protected void doDynamicUpdate(
286284
session
287285
);
288286

289-
// and then execute them
290-
final MutationExecutorService mutationExecutorService = session.getSessionFactory()
291-
.getServiceRegistry()
292-
.getService( MutationExecutorService.class );
293-
294287
final ReactiveMutationExecutor mutationExecutor = mutationExecutor( session, dynamicUpdateGroup );
295288

296289
decomposeForUpdate(
@@ -300,7 +293,9 @@ protected void doDynamicUpdate(
300293
valuesAnalysis,
301294
mutationExecutor,
302295
dynamicUpdateGroup,
303-
(attributeIndex, attribute) -> dirtinessChecker.include( attributeIndex, (SingularAttributeMapping) attribute ) ? AttributeAnalysis.DirtynessStatus.CONSIDER_LIKE_DIRTY : AttributeAnalysis.DirtynessStatus.NOT_DIRTY,
296+
(attributeIndex, attribute) -> dirtinessChecker.include( attributeIndex, (SingularAttributeMapping) attribute )
297+
? AttributeAnalysis.DirtynessStatus.CONSIDER_LIKE_DIRTY
298+
: AttributeAnalysis.DirtynessStatus.NOT_DIRTY,
304299
session
305300
);
306301
bindPartitionColumnValueBindings( oldValues, session, mutationExecutor.getJdbcValueBindings() );
@@ -367,7 +362,8 @@ protected void doStaticUpdate(
367362
entity,
368363
valuesAnalysis,
369364
valuesAnalysis.getTablesNeedingUpdate()::contains,
370-
(statementDetails, affectedRowCount, batchPosition) -> identifiedResultsCheck( statementDetails, affectedRowCount, batchPosition, entityPersister(), id, factory() ),
365+
(statementDetails, affectedRowCount, batchPosition)
366+
-> identifiedResultsCheck( statementDetails, affectedRowCount, batchPosition, entityPersister(), id, factory() ),
371367
session
372368
)
373369
.whenComplete( (o, throwable) -> mutationExecutor.release() )

hibernate-reactive-core/src/main/java/org/hibernate/reactive/session/impl/ReactiveStatelessSessionImpl.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
import static org.hibernate.internal.util.StringHelper.isEmpty;
101101
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
102102
import static org.hibernate.proxy.HibernateProxy.extractLazyInitializer;
103+
import static org.hibernate.reactive.id.impl.IdentifierGeneration.castToIdentifierType;
103104
import static org.hibernate.reactive.persister.entity.impl.ReactiveEntityPersister.forceInitialize;
104105
import static org.hibernate.reactive.session.impl.SessionUtil.checkEntityFound;
105106
import static org.hibernate.reactive.util.impl.CompletionStages.completedFuture;
@@ -249,7 +250,8 @@ public CompletionStage<Void> reactiveInsert(Object entity) {
249250
final Generator generator = persister.getGenerator();
250251
if ( !generator.generatedOnExecution() ) {
251252
return generateId( entity, generator )
252-
.thenCompose( id -> {
253+
.thenCompose( generatedId -> {
254+
final Object id = castToIdentifierType( generatedId, persister );
253255
if ( persister.isVersioned() ) {
254256
if ( seedVersion( entity, state, persister, this ) ) {
255257
persister.setValues( entity, state );

0 commit comments

Comments
 (0)