Skip to content

Commit bd5fd6f

Browse files
committed
Upgrade Hibernate ORM to 7.0
1 parent 7eda8a9 commit bd5fd6f

File tree

83 files changed

+1086
-1188
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1086
-1188
lines changed

hibernate-reactive-core/src/main/java/org/hibernate/reactive/adaptor/impl/ResultSetAdaptor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@
3636
import java.util.NoSuchElementException;
3737
import java.util.function.Function;
3838

39-
import org.hibernate.engine.jdbc.BlobProxy;
40-
import org.hibernate.engine.jdbc.ClobProxy;
39+
import org.hibernate.engine.jdbc.proxy.BlobProxy;
40+
import org.hibernate.engine.jdbc.proxy.ClobProxy;
4141
import org.hibernate.type.descriptor.jdbc.JdbcType;
4242

4343
import io.vertx.core.buffer.Buffer;

hibernate-reactive-core/src/main/java/org/hibernate/reactive/boot/spi/ReactiveMetadataImplementor.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import org.hibernate.boot.spi.AbstractDelegatingMetadata;
99
import org.hibernate.boot.spi.MetadataImplementor;
10-
import org.hibernate.engine.spi.SessionFactoryImplementor;
1110
import org.hibernate.query.named.NamedObjectRepository;
1211
import org.hibernate.reactive.query.internal.ReactiveNamedObjectRepositoryImpl;
1312

@@ -18,7 +17,7 @@ public ReactiveMetadataImplementor(MetadataImplementor delegate) {
1817
}
1918

2019
@Override
21-
public NamedObjectRepository buildNamedQueryRepository(SessionFactoryImplementor sessionFactory) {
22-
return new ReactiveNamedObjectRepositoryImpl( delegate().buildNamedQueryRepository( sessionFactory ) );
20+
public NamedObjectRepository buildNamedQueryRepository() {
21+
return new ReactiveNamedObjectRepositoryImpl( super.buildNamedQueryRepository() );
2322
}
2423
}

hibernate-reactive-core/src/main/java/org/hibernate/reactive/engine/ReactiveActionQueue.java

+30-86
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@
2121
import org.hibernate.AssertionFailure;
2222
import org.hibernate.HibernateException;
2323
import org.hibernate.PropertyValueException;
24+
import org.hibernate.TransientObjectException;
25+
import org.hibernate.action.internal.AbstractEntityInsertAction;
2426
import org.hibernate.action.internal.BulkOperationCleanupAction;
2527
import org.hibernate.action.internal.EntityDeleteAction;
2628
import org.hibernate.action.internal.UnresolvedEntityInsertActions;
2729
import org.hibernate.action.spi.AfterTransactionCompletionProcess;
2830
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
2931
import org.hibernate.action.spi.Executable;
3032
import org.hibernate.cache.CacheException;
33+
import org.hibernate.engine.internal.NonNullableTransientDependencies;
3134
import org.hibernate.engine.spi.ActionQueue;
3235
import org.hibernate.engine.spi.ComparableExecutable;
3336
import org.hibernate.engine.spi.EntityEntry;
3437
import org.hibernate.engine.spi.ExecutableList;
3538
import org.hibernate.engine.spi.SessionFactoryImplementor;
3639
import org.hibernate.engine.spi.SharedSessionContractImplementor;
37-
import org.hibernate.metadata.ClassMetadata;
3840
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
3941
import org.hibernate.proxy.HibernateProxy;
4042
import org.hibernate.proxy.LazyInitializer;
@@ -59,7 +61,6 @@
5961

6062
import static java.lang.invoke.MethodHandles.lookup;
6163
import static org.hibernate.reactive.logging.impl.LoggerFactory.make;
62-
import static org.hibernate.reactive.util.impl.CompletionStages.failedFuture;
6364
import static org.hibernate.reactive.util.impl.CompletionStages.loop;
6465
import static org.hibernate.reactive.util.impl.CompletionStages.voidFuture;
6566

@@ -520,11 +521,21 @@ public CompletionStage<Void> executeInserts() {
520521
*/
521522
public CompletionStage<Void> executeActions() {
522523
if ( hasUnresolvedEntityInsertActions() ) {
523-
return failedFuture( new IllegalStateException( "About to execute actions, but there are unresolved entity insert actions." ) );
524+
final AbstractEntityInsertAction insertAction = unresolvedInsertions
525+
.getDependentEntityInsertActions()
526+
.iterator()
527+
.next();
528+
final NonNullableTransientDependencies transientEntities = insertAction.findNonNullableTransientEntities();
529+
final Object transientEntity = transientEntities.getNonNullableTransientEntities().iterator().next();
530+
final String path = transientEntities.getNonNullableTransientPropertyPaths(transientEntity).iterator().next();
531+
//TODO: should be TransientPropertyValueException
532+
throw new TransientObjectException( "Persistent instance of '" + insertAction.getEntityName()
533+
+ "' with id '" + insertAction.getId()
534+
+ "' references an unsaved transient instance via attribute '" + path
535+
+ "' (save the transient instance before flushing)" );
524536
}
525537

526538
CompletionStage<Void> ret = voidFuture();
527-
528539
for ( OrderedActions action : ORDERED_OPERATIONS ) {
529540
ret = ret.thenCompose( v -> executeActions( action.getActions( this ) ) );
530541
}
@@ -738,26 +749,6 @@ public int numberOfInsertions() {
738749
return insertions.size();
739750
}
740751

741-
// public TransactionCompletionProcesses getTransactionCompletionProcesses() {
742-
// return new TransactionCompletionProcesses( beforeTransactionProcesses(), afterTransactionProcesses() );
743-
// }
744-
//
745-
// /**
746-
// * Bind transaction completion processes to make them shared between primary and secondary session.
747-
// * Transaction completion processes are always executed by transaction owner (primary session),
748-
// * but can be registered using secondary session too.
749-
// *
750-
// * @param processes Transaction completion processes.
751-
// * @param isTransactionCoordinatorShared Flag indicating shared transaction context.
752-
// */
753-
// public void setTransactionCompletionProcesses(
754-
// TransactionCompletionProcesses processes,
755-
// boolean isTransactionCoordinatorShared) {
756-
// this.isTransactionCoordinatorShared = isTransactionCoordinatorShared;
757-
// this.beforeTransactionProcesses = processes.beforeTransactionCompletionProcesses;
758-
// this.afterTransactionProcesses = processes.afterTransactionCompletionProcesses;
759-
// }
760-
761752
public void sortCollectionActions() {
762753
if ( isOrderUpdatesEnabled() ) {
763754
// sort the updates by fk
@@ -864,32 +855,6 @@ public void unScheduleDeletion(EntityEntry entry, Object rescuedEntity) {
864855
throw new AssertionFailure( "Unable to perform un-delete for instance " + entry.getEntityName() );
865856
}
866857

867-
// /**
868-
// * Used by the owning session to explicitly control serialization of the action queue
869-
// *
870-
// * @param oos The stream to which the action queue should get written
871-
// *
872-
// * @throws IOException Indicates an error writing to the stream
873-
// */
874-
// public void serialize(ObjectOutputStream oos) throws IOException {
875-
// LOG.trace( "Serializing action-queue" );
876-
// if ( unresolvedInsertions == null ) {
877-
// unresolvedInsertions = new UnresolvedEntityInsertActions();
878-
// }
879-
// unresolvedInsertions.serialize( oos );
880-
//
881-
// for ( ListProvider<?> p : EXECUTABLE_LISTS_MAP.values() ) {
882-
// ExecutableList<?> l = p.get( this );
883-
// if ( l == null ) {
884-
// oos.writeBoolean( false );
885-
// }
886-
// else {
887-
// oos.writeBoolean( true );
888-
// l.writeExternal( oos );
889-
// }
890-
// }
891-
// }
892-
893858
private abstract static class AbstractTransactionCompletionProcessQueue<T,U> {
894859
final ReactiveSession session;
895860

@@ -994,21 +959,6 @@ public CompletionStage<Void> afterTransactionCompletion(boolean success) {
994959
}
995960
}
996961

997-
// /**
998-
// * Wrapper class allowing to bind the same transaction completion process queues in different sessions.
999-
// */
1000-
// public static class TransactionCompletionProcesses {
1001-
// private final BeforeTransactionCompletionProcessQueue beforeTransactionCompletionProcesses;
1002-
// private final AfterTransactionCompletionProcessQueue afterTransactionCompletionProcesses;
1003-
//
1004-
// private TransactionCompletionProcesses(
1005-
// BeforeTransactionCompletionProcessQueue beforeTransactionCompletionProcessQueue,
1006-
// AfterTransactionCompletionProcessQueue afterTransactionCompletionProcessQueue) {
1007-
// this.beforeTransactionCompletionProcesses = beforeTransactionCompletionProcessQueue;
1008-
// this.afterTransactionCompletionProcesses = afterTransactionCompletionProcessQueue;
1009-
// }
1010-
// }
1011-
1012962
/**
1013963
* Order the {@link #insertions} queue such that we group inserts against the same entity together (without
1014964
* violating constraints). The original order is generated by cascade order, which in turn is based on the
@@ -1152,26 +1102,23 @@ public void sort(List<ReactiveEntityInsertActionHolder> insertions) {
11521102
*/
11531103
private void addParentChildEntityNames(ReactiveEntityInsertAction action, BatchIdentifier batchIdentifier) {
11541104
Object[] propertyValues = action.getState();
1155-
ClassMetadata classMetadata = action.getPersister().getClassMetadata();
1156-
if ( classMetadata != null ) {
1157-
Type[] propertyTypes = classMetadata.getPropertyTypes();
1158-
Type identifierType = classMetadata.getIdentifierType();
1159-
1160-
for ( int i = 0; i < propertyValues.length; i++ ) {
1161-
Object value = propertyValues[i];
1162-
if (value!=null) {
1163-
Type type = propertyTypes[i];
1164-
addParentChildEntityNameByPropertyAndValue( action, batchIdentifier, type, value );
1165-
}
1105+
Type[] propertyTypes = action.getPersister().getPropertyTypes();
1106+
Type identifierType = action.getPersister().getIdentifierType();
1107+
1108+
for ( int i = 0; i < propertyValues.length; i++ ) {
1109+
Object value = propertyValues[i];
1110+
if (value!=null) {
1111+
Type type = propertyTypes[i];
1112+
addParentChildEntityNameByPropertyAndValue( action, batchIdentifier, type, value );
11661113
}
1114+
}
11671115

1168-
if ( identifierType.isComponentType() ) {
1169-
CompositeType compositeType = (CompositeType) identifierType;
1170-
Type[] compositeIdentifierTypes = compositeType.getSubtypes();
1116+
if ( identifierType.isComponentType() ) {
1117+
CompositeType compositeType = (CompositeType) identifierType;
1118+
Type[] compositeIdentifierTypes = compositeType.getSubtypes();
11711119

1172-
for ( Type type : compositeIdentifierTypes ) {
1173-
addParentChildEntityNameByPropertyAndValue( action, batchIdentifier, type, null );
1174-
}
1120+
for ( Type type : compositeIdentifierTypes ) {
1121+
addParentChildEntityNameByPropertyAndValue( action, batchIdentifier, type, null );
11751122
}
11761123
}
11771124
}
@@ -1275,10 +1222,9 @@ public boolean equals(Object o) {
12751222
if ( this == o ) {
12761223
return true;
12771224
}
1278-
if ( !( o instanceof BatchIdentifier ) ) {
1225+
if ( !( o instanceof BatchIdentifier that ) ) {
12791226
return false;
12801227
}
1281-
BatchIdentifier that = (BatchIdentifier) o;
12821228
return Objects.equals( entityName, that.entityName );
12831229
}
12841230

@@ -1315,9 +1261,7 @@ boolean hasAnyChildEntityNames(BatchIdentifier batchIdentifier) {
13151261
/**
13161262
* Check if this {@link BatchIdentifier} has a parent or grandparent
13171263
* matching the given {@link BatchIdentifier reference.
1318-
*
13191264
* @param batchIdentifier {@link BatchIdentifier} reference
1320-
*
13211265
* @return this {@link BatchIdentifier} has a parent matching the given {@link BatchIdentifier reference
13221266
*/
13231267
boolean hasParent(BatchIdentifier batchIdentifier) {

hibernate-reactive-core/src/main/java/org/hibernate/reactive/engine/jdbc/mutation/internal/ReactiveMutationExecutorStandard.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.sql.SQLException;
1010
import java.util.concurrent.CompletionStage;
1111

12+
import org.hibernate.engine.jdbc.batch.spi.Batch;
1213
import org.hibernate.engine.jdbc.mutation.JdbcValueBindings;
1314
import org.hibernate.engine.jdbc.mutation.OperationResultChecker;
1415
import org.hibernate.engine.jdbc.mutation.ParameterUsage;
@@ -99,7 +100,8 @@ protected void performSelfExecutingOperations(
99100
@Override
100101
protected void performBatchedOperations(
101102
ValuesAnalysis valuesAnalysis,
102-
TableInclusionChecker inclusionChecker) {
103+
TableInclusionChecker inclusionChecker,
104+
Batch.StaleStateMapper staleStateMapper) {
103105
throw LOG.nonReactiveMethodCall( "performReactiveBatchedOperations" );
104106
}
105107

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

+49-48
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import org.hibernate.event.spi.EventSource;
2626
import org.hibernate.generator.BeforeExecutionGenerator;
2727
import org.hibernate.generator.Generator;
28-
import org.hibernate.id.Assigned;
28+
import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
2929
import org.hibernate.id.IdentifierGenerationException;
3030
import org.hibernate.jpa.event.spi.CallbackRegistry;
3131
import org.hibernate.jpa.event.spi.CallbackRegistryConsumer;
@@ -134,7 +134,7 @@ protected CompletionStage<Void> reactiveSaveWithGeneratedId(
134134
// and is not yet available
135135
generatedId = null;
136136
}
137-
else if ( generator instanceof Assigned ) {
137+
else if ( !generator.generatesOnInsert() ) {
138138
// get it from the entity later, since we need
139139
// the @PrePersist callback to happen first
140140
generatedId = null;
@@ -144,55 +144,58 @@ else if ( generator instanceof Assigned ) {
144144
// the entity instance, so it will be available
145145
// to the entity in the @PrePersist callback
146146
if ( generator instanceof ReactiveIdentifierGenerator ) {
147-
return ( (ReactiveIdentifierGenerator<?>) generator )
148-
.generate( ( ReactiveConnectionSupplier ) source, entity )
149-
.thenApply( id -> castToIdentifierType( id, persister ) )
150-
.thenCompose( gid -> performSaveWithId(
151-
entity,
152-
context,
153-
source,
154-
persister,
155-
generator,
156-
gid,
157-
requiresImmediateIdAccess,
158-
false
159-
) );
147+
return generateId( entity, source, (ReactiveIdentifierGenerator<?>) generator, persister )
148+
.thenCompose( gid -> {
149+
if ( gid == SHORT_CIRCUIT_INDICATOR ) {
150+
source.getIdentifier( entity );
151+
return voidFuture();
152+
}
153+
persister.setIdentifier( entity, gid, source );
154+
return reactivePerformSave(
155+
entity,
156+
gid,
157+
persister,
158+
generatedOnExecution,
159+
context,
160+
source,
161+
false
162+
);
163+
} );
160164
}
161165

162166
generatedId = ( (BeforeExecutionGenerator) generator ).generate( source, entity, null, INSERT );
167+
if ( generatedId == SHORT_CIRCUIT_INDICATOR ) {
168+
source.getIdentifier( entity );
169+
return voidFuture();
170+
}
171+
persister.setIdentifier( entity, generatedId, source );
163172
}
164173
final Object id = castToIdentifierType( generatedId, persister );
165-
return reactivePerformSave( entity, id, persister, generatedOnExecution, context, source, requiresImmediateIdAccess );
174+
final boolean delayIdentityInserts = !source.isTransactionInProgress() && !requiresImmediateIdAccess && generatedOnExecution;
175+
return reactivePerformSave( entity, id, persister, generatedOnExecution, context, source, delayIdentityInserts );
166176
}
167177

168-
private CompletionStage<Void> performSaveWithId(
178+
private CompletionStage<Object> generateId(
169179
Object entity,
170-
C context,
171180
EventSource source,
172-
EntityPersister persister,
173-
Generator generator,
174-
Object generatedId,
175-
boolean requiresImmediateIdAccess,
176-
boolean generatedOnExecution) {
177-
if ( generatedId == null ) {
178-
throw new IdentifierGenerationException( "null id generated for: " + entity.getClass() );
179-
}
180-
if ( generatedId == SHORT_CIRCUIT_INDICATOR ) {
181-
source.getIdentifier( entity );
182-
return voidFuture();
183-
}
184-
if ( LOG.isDebugEnabled() ) {
185-
LOG.debugf(
186-
"Generated identifier: %s, using strategy: %s",
187-
persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ),
188-
generator.getClass().getName()
189-
);
190-
}
191-
final boolean delayIdentityInserts =
192-
!source.isTransactionInProgress()
193-
&& !requiresImmediateIdAccess
194-
&& generatedOnExecution;
195-
return reactivePerformSave( entity, generatedId, persister, false, context, source, delayIdentityInserts );
181+
ReactiveIdentifierGenerator<?> generator,
182+
EntityPersister persister) {
183+
return generator
184+
.generate( (ReactiveConnectionSupplier) source, entity )
185+
.thenApply( id -> castToIdentifierType( id, persister ) )
186+
.thenCompose( generatedId -> {
187+
if ( generatedId == null ) {
188+
return failedFuture( new IdentifierGenerationException( "null id generated for: " + entity.getClass() ) );
189+
}
190+
if ( LOG.isDebugEnabled() ) {
191+
LOG.debugf(
192+
"Generated identifier: %s, using strategy: %s",
193+
persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ),
194+
generator.getClass().getName()
195+
);
196+
}
197+
return completedFuture( generatedId );
198+
} );
196199
}
197200

198201
/**
@@ -229,13 +232,11 @@ protected CompletionStage<Void> reactivePerformSave(
229232
processIfSelfDirtinessTracker( entity, SelfDirtinessTracker::$$_hibernate_clearDirtyAttributes );
230233
processIfManagedEntity( entity, managedEntity -> managedEntity.$$_hibernate_setUseTracker( true ) );
231234

232-
if ( persister.getGenerator() instanceof Assigned ) {
235+
final Generator generator = persister.getGenerator();
236+
if ( !generator.generatesOnInsert() || generator instanceof CompositeNestedGeneratedValueGenerator ) {
233237
id = persister.getIdentifier( entity, source );
234238
if ( id == null ) {
235-
throw new IdentifierGenerationException(
236-
"Identifier of entity '" + persister.getEntityName()
237-
+ "' must be manually assigned before calling 'persist()'"
238-
);
239+
return failedFuture( new IdentifierGenerationException( "Identifier of entity '" + persister.getEntityName() + "' must be manually assigned before calling 'persist()'" ) );
239240
}
240241
}
241242

@@ -420,7 +421,7 @@ private CompletionStage<AbstractEntityInsertAction> addInsertAction(
420421
boolean useIdentityColumn,
421422
EventSource source,
422423
boolean shouldDelayIdentityInserts) {
423-
final ReactiveActionQueue actionQueue = source.unwrap( ReactiveSession.class ).getReactiveActionQueue();
424+
final ReactiveActionQueue actionQueue = source.unwrap(ReactiveSession.class).getReactiveActionQueue();
424425
if ( useIdentityColumn ) {
425426
final ReactiveEntityIdentityInsertAction insert = new ReactiveEntityIdentityInsertAction(
426427
values, entity, persister, false, source, shouldDelayIdentityInserts

0 commit comments

Comments
 (0)