@@ -169,15 +169,16 @@ public GeneratedValues update(
169
169
SharedSessionContractImplementor session ) {
170
170
final EntityVersionMapping versionMapping = entityPersister ().getVersionMapping ();
171
171
if ( versionMapping != null ) {
172
- final Supplier <GeneratedValues > generatedValuesAccess = handlePotentialImplicitForcedVersionIncrement (
173
- entity ,
174
- id ,
175
- values ,
176
- oldVersion ,
177
- incomingDirtyAttributeIndexes ,
178
- session ,
179
- versionMapping
180
- );
172
+ final var generatedValuesAccess =
173
+ handlePotentialImplicitForcedVersionIncrement (
174
+ entity ,
175
+ id ,
176
+ values ,
177
+ oldVersion ,
178
+ incomingDirtyAttributeIndexes ,
179
+ session ,
180
+ versionMapping
181
+ );
181
182
if ( generatedValuesAccess != null ) {
182
183
return generatedValuesAccess .get ();
183
184
}
@@ -389,57 +390,71 @@ protected Supplier<GeneratedValues> handlePotentialImplicitForcedVersionIncremen
389
390
int [] incomingDirtyAttributeIndexes ,
390
391
SharedSessionContractImplementor session ,
391
392
EntityVersionMapping versionMapping ) {
392
- // handle case where the only value being updated is the version.
393
- // we handle this case specially from `#coordinateUpdate` to leverage
394
- // `#doVersionUpdate`
395
- final boolean isSimpleVersionUpdate ;
393
+ // Handle a case where the only value being updated is the version.
394
+ // We treat this case specially in `#coordinateUpdate` to leverage
395
+ // `#doVersionUpdate`.
396
396
final Object newVersion ;
397
-
398
- if ( incomingDirtyAttributeIndexes != null ) {
399
- if ( incomingDirtyAttributeIndexes .length == 1
400
- && versionMapping .getVersionAttribute () == entityPersister ().getAttributeMapping ( incomingDirtyAttributeIndexes [0 ] ) ) {
401
- // special case of only the version attribute itself as dirty
402
- isSimpleVersionUpdate = true ;
403
- newVersion = values [ incomingDirtyAttributeIndexes [0 ]];
404
- }
405
- else if ( incomingDirtyAttributeIndexes .length == 0 && oldVersion != null ) {
406
- isSimpleVersionUpdate = !versionMapping .areEqual (
407
- values [ versionMapping .getVersionAttribute ().getStateArrayPosition () ],
408
- oldVersion ,
409
- session
410
- );
411
- newVersion = values [ versionMapping .getVersionAttribute ().getStateArrayPosition ()];
412
- }
413
- else {
414
- isSimpleVersionUpdate = false ;
415
- newVersion = null ;
416
- }
417
- }
418
- else {
419
- isSimpleVersionUpdate = false ;
420
- newVersion = null ;
397
+ if ( hasUpdateGeneratedValues () ) {
398
+ // if we have any fields generated by the UPDATE event,
399
+ // then we have to include the generated fields in the
400
+ // update statement
401
+ return null ;
421
402
}
422
-
423
- if ( isSimpleVersionUpdate ) {
424
- // we have just the version being updated - use the special handling
425
- assert newVersion != null ;
426
- final GeneratedValues generatedValues = doVersionUpdate ( entity , id , newVersion , oldVersion , session );
427
- return () -> generatedValues ;
403
+ else if ( incomingDirtyAttributeIndexes != null ) {
404
+ switch ( incomingDirtyAttributeIndexes .length ) {
405
+ case 1 :
406
+ final int dirtyAttributeIndex = incomingDirtyAttributeIndexes [0 ];
407
+ final var versionAttribute = versionMapping .getVersionAttribute ();
408
+ final var dirtyAttribute = entityPersister ().getAttributeMapping ( dirtyAttributeIndex );
409
+ if ( versionAttribute == dirtyAttribute ) {
410
+ // only the version attribute itself is dirty
411
+ newVersion = values [dirtyAttributeIndex ];
412
+ }
413
+ else {
414
+ // the dirty field is some other field
415
+ return null ;
416
+ }
417
+ break ;
418
+ case 0 :
419
+ if ( oldVersion != null ) {
420
+ newVersion = values [versionMapping .getVersionAttribute ().getStateArrayPosition ()];
421
+ if ( versionMapping .areEqual ( newVersion , oldVersion , session ) ) {
422
+ return null ;
423
+ }
424
+ }
425
+ else {
426
+ return null ;
427
+ }
428
+ break ;
429
+ default :
430
+ return null ;
431
+ }
428
432
}
429
433
else {
430
434
return null ;
431
435
}
436
+
437
+ // we have just the version being updated - use the special handling
438
+ assert newVersion != null ;
439
+ final GeneratedValues generatedValues = doVersionUpdate ( entity , id , newVersion , oldVersion , session );
440
+ return () -> generatedValues ;
441
+ }
442
+
443
+ private boolean hasUpdateGeneratedValues () {
444
+ final var entityMetamodel = entityPersister ().getEntityMetamodel ();
445
+ return entityMetamodel .hasUpdateGeneratedValues ()
446
+ || entityMetamodel .hasPreUpdateGeneratedValues ();
432
447
}
433
448
434
449
private static boolean isValueGenerated (Generator generator ) {
435
450
return generator != null
436
- && generator .generatesOnUpdate ()
437
- && generator .generatedOnExecution ();
451
+ && generator .generatesOnUpdate ()
452
+ && generator .generatedOnExecution ();
438
453
}
439
454
440
455
private static boolean isValueGenerationInSql (Generator generator , Dialect dialect ) {
441
456
assert isValueGenerated ( generator );
442
- return ( (OnExecutionGenerator ) generator ).referenceColumnsInSql (dialect );
457
+ return ( (OnExecutionGenerator ) generator ).referenceColumnsInSql ( dialect );
443
458
}
444
459
445
460
/**
0 commit comments